ES6 简介
- 欧洲计算机制造商协会
- 标准化组织 ECMAScript=由 ECMA 这个标准化组织制定的一个语言标准 ECMAScript=语法+API
ES 与 JavaScript 的关系
- JavaScript(浏览器端)=ECMAScript(语法+API)+DOM+BOM
let 和 const
- var ,let 代替 var,声明变量,变量一旦初始化之后,还可以重新赋值
- const 声明常量 constant,常量一旦初始化,就不能重新赋值了,否则就会报错
- const 就是为了那些一旦初始化就不希望重新赋值的情况设计的
- 不知道用什么的时候,就用 const
- 注意:
- 使用 const 声明常量,一旦声明,就必须立即初始化,不能留到以后赋值
- const 声明的常量,允许在不重新赋值的情况下修改它的值
let const 与 var 的区别
1.重复声明
- 已经存在的变量或常量,又声明的一遍
- var 允许重复声明,let,const 不允许
2.变量提升
- var 会提升变量的声明到当前作用域的顶部[变量可以在声明之前使用]
- let,const 不存在变量提升
- 养成良好的编程习惯,对于所有的变量或常量,做到先声明,后使用
3.暂时性死区
- 只要作用域内存在 let,const,它们所声明的变量或常量就自动“绑定”这个区域,不再受到外部作用域的影响 let const 存在暂时性死区
let a=2;
let b=1;
function func(){
console.log(b);//1
//console.log(a);
//let a=1;
}
func();
4.window 对象的属性和方法(全局作用域中)
- 全局作用域中,var 声明的变量,通过 function 声明的函数,会自动变成 window 对象的属性或方法,, let const 不会
//var /function
var age=18;
function add(){}
console.log(window.age);//18
console.log(window.add===add);//true
//let/const
let age=18;
const add=function (){}
console.log(window.age);//undefined
console.log(window.add===add);//undefined
块级作用域
- var 没有块级作用域
for(var i=0;i<3;i++){
//console.log(i);//0,1,2
}
//全局作用域,所以是 3
console.log(i);//3
- let / const 有块级作用域
for(let i=0; i<3; i++){
//console.log(i);//0,1,2
}
i 和 for 共同构成了一个块级作用域
console.log(i);// i 没有定义,报错
- 作用域链 : 内层作用域->外层作用域->...->全局作用域
function func(){
for(let i=0;i<3;i++){
console.log(i);//0,1,2
}
}
func();
console.log(i);//报错
- 有哪些块级作用域
- 函数作用域 function(){}
- 对象本身的花括号,不构成作用域 const person={}
{
let age=18;
console.log(age);//18
}
console.log(age);
{}
for(){}
while(){}
do{}while()
if(){}
switch(){}
let const 的应用 [使用 let const]
<title>Title</title>
<style>
body{
padding: 50px 0 0 150px;
}
.btn{
width: 100px;
height: 100px;
margin-right: 20px;
font-size: 80px;
cursor: pointer;
}
</style>
</head>
<body>
<button class="btn">0</button>
<button class="btn">1</button>
<button class="btn">2</button>
</body>
//1.var [3 3 3]
var btns=document.querySelectorAll('.btn');
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener('click',function (){
console.log(i);
},false);
}
//2.闭包 [0 1 2]
var btns=document.querySelectorAll('.btn');
for (var i = 0; i < btns.length; i++) {
(function (index){
btns[index].addEventListener('click',function (){
console.log(index);
},false);
})(i);
}
//3.let /const
let btns=document.querySelectorAll('.btn');
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener('click',function (){
console.log(i);
},false);
}
模板字符与箭头函数
模板字符串是什么
-
一般字符串: \'alex\' "alex"
-
模板字符串:
`alex` -
模板字符串和一般字符串的区别
const person = {
username: 'Alex',
age: 18,
sex: 'male'
};
//一般字符串
// const info = '我的名字是:' + person.username + ',性别:'
// + person.sex + ',今年' + person.age + '岁了';
// console.log(info);
//模板字符串
const info=`我的名字是:${person.username},性别:${person.sex},今年${person.age}岁了`;
console.log(info);
模板字符串的注意事项
- 1.输出多行字符串
- 2.输出`和\等特殊字符,转义字符
- 3.模板字符串的注入
<script> //todo 1.输出多行字符串 //一般字符串 const info='第 1 行\n 第 2 行'; console.log(info); //模板字符串 const info=`第 1 行 // 第 2 行`; console.log(info); //模板字符串中,所有的空格/换行或缩进都会被保留在输出之中 //todo 2.输出`和\等特殊字符,,转义字符 const info=`'\`\\`;// '`\ console.log(info); //todo 3.模板字符串的注入 // ${} const username='alex'; const person={age:18,sex:'male'}; const getSex=function (sex){ return sex==='male'?'男':'女'; }; const info=`${username},${person.age+2},${getSex(person.sex)}`; console.log(info); //只要最终可以得出一个值的就可以通过${}注入到模板字符串中 </script>
模板字符串的应用[重要]
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body{
padding: 50px 0 0 300px;
font-size: 22px;
}
ul{
padding: 0;
}
p{
margin-bottom: 10px;
}
</style>
</head>
<body>
<p>学生信息表</p>
<ul id="list">
<li style="list-style: none;">信息加载中...</li>
</ul>
<script>
//数据 Ajax
const students=[
{
username:'Alex',
age:18,
sex:'male'
},
{
username:'ZhangSan',
age:28,
sex:'female'
},
{
username:'LiSi',
age:20,
sex:'female'
}
];
const list=document.getElementById('list');
let html='';
for (let i = 0; i < students.length; i++) {
html+=`<li>我的名字是:${students[i].username},${students[i].sex},${students[i].age}</li>`;
}
// console.log(html);
list.innerHTML=html;
</script>
</body>
</html>
箭头函数是什么
- ()=>{};
//1.认识箭头函数
const add = (x, y) => {
return x + y;
};
console.log(1, 1);
//2.箭头函数的结构
const/let 函数名= 参数 => 函数体
//3,如何将一般函数改写成箭头函数
//声明形式
function add(){}
//声明形式->函数表达式形式
const add=function (){};
//函数表达式形式->箭头函数
const add=()=>{};
箭头函数的注意事项
//1.单个参数 [可以省略圆括号]
const add=x=>{
return x+1;
};
console.log(add(1));
//2.无参数或多个参数不能省略圆括号
const add=()=>{
return 1+1;
};
const add=(x,y)=>{
return x+y;
};
console.log(add(1,2));
//3.单行函数体
//单行函数体可以同时省略{}和 return
const add=(x,y)=> x+y;
console.log(add(1,2));
//4.多行函数体不能再化简了
const add=(x,y)=> {
const sum = x + y;
return sum;
};
console.log(add(1,4));
//5.单行对象
const add=(x,y)=>{
return{
value:x+y
};
};
const add=(x,y)=>({value:x+y});//{value: 2}
//如果箭头函数返回单行对象,可以在{}外面加上(), 让浏览器不再认为那是函数体的花括号
// const add=(x,y)=>[x,y];
//console.log(add(1,1));//(2) [1, 1]
非箭头函数中的 this 指向 [重要]
- 只有在函数调用的时候 this 指向才确定,不调用的时候,不知道指向谁
- this 指向和函数在哪儿调用没关系,只和谁在调用有关,就指向谁
//1.全局作用域中的 this 指向
//console.log(this);//window
//2.一般函数(非箭头函数)中的 this 指向
//'use strict';
function add(){
console.log(this);
}
//严格模式下就指向 undefined
//add();//undefined->window(非严格模式下)
window.add();
const calc={
add:add
};
// calc.add(); //calc
const adder=calc.add;
adder();//undefined->window(非严格模式下)
document.onclick=function (){
console.log(this);
};
document.onclick();//一点击指 t#document
function Person(username){
this.username=username;
console.log(this);
}
const p=new Person('Alex');
箭头函数中的 this 指向 [重要]
//1.箭头函数中的 this 指向
//箭头函数没有自己的 this
const calc={
add:()=>{
console.log(this);
}
};
calc.add();//window
//2.练习
'use strict';
const calc={
add:function (){
//this addFn
const adder=()=>{
console.log(this);
};
adder();
}
};
//谁调用他,他里面的 this,就指向谁
//calc.add();//add 的 this 指向 calc
const addFn=calc.add;//赋值
addFn();//无具体的对象 undefined->window(非严格模式下)
不使用箭头函数的场景
- 1.作为构造函数
- 2.需要 this 指向调用对象的时候
- 3.需要使用 arguments 的时候,数组
//1.作为构造函数
//箭头函数没有 this
const Person=()=>{};
new Person();
//2.需要 this 指向调用对象的时候,[不要使用箭头函数] //因为箭头函数没有自己的 this
document.onclick=function (){
console.log(this);
}
document.addEventListener('click', function(){
console.log(this);//#document
},false)
document.addEventListener('click', ()=>{
console.log(this);//window
},false)
//3.需要使用 arguments 的时候,箭头函数中没有 arguments
function add(){
console.log(arguments);
}
add(1,2);
//Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
// const add=()=> console.log(arguments);
// add();
//剩余参数
箭头函数的应用[重要]
- 箭头函数没有自身的 this,他的 this 要往上一层寻找
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body{
padding: 50px 0 0 250px;
font-size: 22px;
font-size: 30px;
}
#btn{
width: 100px;
height: 100px;
margin-right: 20px;
font-size: 30px;
cursor: pointer;
}
</style>
</head>
<body>
<button id="btn">开始</button>
<span id="result">0</span>
<script>
const btn=document.getElementById('btn');
const result=document.getElementById('result');
// const timer = {
// time:0,
// start:function (){
// //this 指向 timer
// var that=this;
// btn.addEventListener('click',function (){
// setInterval(function (){
// //console.log(this);//undefined -> 指向 window 对象[非严格模式下]
// // this.time++;
// // result.innerHTML=this.time;
// that.time++;
// result.innerHTML=that.time;
// },1000);
// },false);
// }
// };
const timer = {
time:0,
start:function (){
//this 指向 timer
btn.addEventListener(
'click',
()=>{//指向 timer 的 this
//this
setInterval( ()=>{//指向上一层的 this
//console.log(this);
this.time++;
result.innerHTML=this.time;
},1000);
},false);
}
};
timer.start();
</script>
</body>
</html>
总结
解构赋值
解构赋值是什么
//1.认识解构赋值
// const arr=[1,2,3];
// const a=arr[0];
// const b=arr[1];
// const c=arr[2];
// console.log(a,b,c);//1 2 3
const [a,b,c]=[1,2,3];
console.log(a,b,c);//1 2 3
//2.什么是解构赋值
//解析某一数据的结构,将我们想要的东西提取出来,赋值给变量或常量
数组解构赋值的原理
- 模式(结构)匹配
- 索引值相同的完成赋值
const[a,[,,b],c]=[1,[2,4,5],3];
console.log(a,b,c);//1 5 3
数组解构赋值的默认值
//1.默认值的基本用法
const [a,b]=[];
const [a,b]=[undefined,undefined];
const [a=1,b=2]=[];
console.log(a,b);
//2.默认值的生效条件
//只有当一个数组成员严格等于(===)undefined 时,对应的默认值才会生效
const [a=1,b=2]=[3,0];//3 0
const [a=1,b=2]=[3,null];//3 null
const [a=1,b=2]=[3];//3 2
console.log(a,b);
//3.默认值表达式
//如果默认值是表达式,默认值表达式是惰性求值的
const func=()=>{
console.log('我被执行了');
return 2;
};
//const [x=func()]=[1];//1
const [x=func()]=[];//我被执行了 2
console.log(x);
数组解构赋值的应用
<p>123</p>
<p>321</p>
<p>34567</p>
<script>
//1.常见的类数组的解构赋值
//arguments
function func(){
console.log(arguments);
console.log(arguments.push);//undefined 只是个类数组
const [a,b]=arguments;
console.log(a,b);
}
func();
func(1,2);//1 2
//NodeList 节点列表
console.log(document.querySelectorAll('p'));//输出内容//NodeList(3) [p,p,p]
const [p1,p2,p3]=document.querySelectorAll('p');
console.log(p1,p2,p3);
//2.函数参数的解构赋值
const array=[1,1];
// const add=arr=>arr[0]+arr[1];
const add=([x=0,y=0])=>x+y;//[x,y]=[1,1]
console.log(add(array));//2
console.log(add([]));//0
//3.交换变量的值
let x=1;
let y=2;
// let tmp=x;
// x=y;
// y=tmp;
// console.log(x,y);//2 1
[x,y]=[y,x];
console.log(x,y);//2 1
对象解构赋值的原理
//1.模式(结构)匹配
{}={}
//2.属性名相同的完成赋值
const {age,username}={username:'Alex',age:18}
const {age:age,username:username}={username:'Alex',age:18}
console.log(age,username);
//起别名
const {age:age,username:uname}={username:'Alex',age:18}
console.log(age,uname);
对象解构赋值的注意事项
- 对象解构赋值的默认值
- 将一个已经声明的变量用于解构赋值
- 可以取到继承的属性
//1.默认值的生效条件
//对象的属性值严格等于 undefined 时,对应的默认值才会生效
const {username='zhangsan',age=0}={username:'alec'};//age:undefined
console.log(username,age);//alec 0
//2.默认值表达式
//如果默认值是表达式,默认值表达式是惰性求值的
//3.将一个已经声明的变量用于解构赋值
//如果将一个已经声明的变量用于对象的解构赋值,整个赋值需在圆括号中进行
// let {x}={x:1};
// console.log(x);//1
let x=2;
({x}={x:1});
// [x]=[1];
console.log(x);//1
//4.可以取到继承的属性
const {a=1}={};
console.log(a);//1
const {toString}={};
console.log(toString);//函数ƒ toString()
// Object.prototype ,,toString 继承对象 Object
console.log(Object.prototype);
console.log({});
对象解构赋值的应用
//1.函数参数的解构赋值
// const logPersonInfo=user=>console.log(user.username,user.age);
const logPersonInfo=({age=0,username='hkj'})=>console.log(username,age);
// logPersonInfo({username:'alex',age:18});//alex 18
logPersonInfo({});//hkj 0
//2.复杂的嵌套
const obj={
x:1,
y:[2,3,4],
z:{
a:5,
b:6
}
};
// const {x,y,z}=obj;
// console.log(x,y,z);
const {
y,
y:[,yy],
z,
z:{
b:b
}
}=obj;//[,yy]=[2,3,4]
console.log(yy,y,z,b);//3 (3)[2, 3, 4] {a: 5, b: 6} 6
其它数据类型的解构赋值
//1.字符串的解构赋值
//''='hello' x
//数组形式的解构赋值
const [a,b,,,c]='hello';
console.log(a,b,c);//h e o
//对象形式的解构赋值
const {0:a,1:b,length}='hello';
console.log(a,b,length);//h e 5
console.log('hello'.length);//5
//字符串既可以按数组形式来解构赋值,也可以按对象形式来解构赋值
//2.数值和布尔值的解构赋值
//先将等号右边的值转为对象
console.log(new Number(123));
const {a=1,toString}=123;
console.log(a,toString);//1 ƒ toString() { [native code] }
//布尔值
const {b=2,toString}=true;
console.log(b,toString);//2 ƒ toString() { [native code] }
//3.undefined 和 null 的解构赋值
//由于 undefined 和 null 无法转为对象,所以对它们进行解构赋值,都会报错
对象形式
const {toString}=undefined;
const {toString}=null;
对象字面看的增强与函数参数默认值
属性和方法的简洁表示法[经常使用]
//1.对象字面量是什么
//实例化构造函数生成对象
const person=new Object();
person.age=18;
person.speak=function (){};
//对象字面量 [用的多]
const person={
age:18,
speak:function (){}
};
//2.属性的简洁表示法
//键名和变量或常量名一样的时候,可以只写一个
const age=18;
const person={
//age:age,
age
};
console.log(person);//{age: 18}
//3.方法的简洁表示法
//方法可以省略冒号和 function 关键字
const person = {
// speak:function(){}
speak() {
}
};
console.log(person);//{speak: ƒ}
方括号语法[了解]
//1.方括号语法的用法
const prop='age';
const person={};
person.prop=18;不可以使用点语法
person[prop]=18;
//方括号语法可以写在对象字面量中
const person={
[prop]:18
};
console.log(person);
//2.方括号中可以放什么
//${}
//[值或通过计算可以得到值的(表达式)]
const prop='age';
const func=()=>'age2';
const person ={
// [prop]:18
// [func()]:18
// ['sex']:'male'
['s'+'ex']:'male'
};
console.log(person);
//3.方括号语法和点语法的区别
//点语法是方括号语法的特殊形式
const person={};
// person.age 等价于 person['age']
//合法标识符:属性名由数字.字母.下划线以及$构成,并且数字还不能打头 的时候可以使用点语法
// age18_$√ 合法标识符可以用来作为变量或常量名
//18age ×
//当你的属性或方法名是合法标识符时,可以使用点语法,其他情况下请使用方括号语法
函数参数的默认值是什么
//1.认识函数参数的默认值
//调用函数的时候传参了,就用传递的参数;如果没传参,就用默认值
multiply(2,1);
multiply(2);
//2.函数参数默认值的基本用法
//(1)
const multiply=(x,y)=>{
if(typeof y==='undefined'){
y=1;
}
return x*y;
}
//(2)
const multiply=(x,y=1)=> x*y;
console.log(multiply(2,2));
函数参数默认值的注意事项
//1.默认值的生效条件
//不传参数,或者明确的传递 undefined 作为参数,只有这两种情况下,默认值才会生效
const multiply=(x,y=1)=> x*y;
console.log(multiply(2,0));//0
console.log(multiply(2,null));//0
console.log(multiply(2,undefined));//2
console.log(multiply(2));//2
//2.默认值表达式
//如果默认值是表达式,默认值表达式是惰性求值的
//3.设置默认值的小技巧
//函数参数的默认值,最好从参数列表的右边开始设置
const multiply=(x=1,y)=> x*y;
console.log(multiply(undefined,2))
函数参数默认值的应用[重点]
//1.接收很多参数的时候
/* 实际开发中,不用这写法
const logUser=(username='zhangsan',age=0,sex='male')=>console.log(username,age,sex)
logUser('Al',19,'male');
logUser()*/
//2.接收一个对象作为参数
/* ×××× const logUser=options=>console.log(options.username,options.age,options.sex);
logUser({
username:'al',
age:19,
sex:'male'
})*/
//注意: options={} <=> {username='zhangsan',age=0,sex='male'}={} 对一个空对象来解构
const logUser=({username='zhangsan',age=0,sex='male'}={})=>console.log(username,age,sex)
// logUser({username:'al'})//al 0 male
// logUser({}) //zhangsan 0 male
logUser(); //zhangsan 0 male //{username='zhangsan',age=0,sex='male'}=undefined











