es6语法
1 箭头函数
- 表达式
- 格式:
var 函数名 = 参数 => 返回值
; - var fn=p=>p;
- var fn=()=>"我没有参数";
- var fn=(n,m)=>n+m;
- 格式:
- 函数体
- 格式:
var 函数名 = 参数 =>{ return 返回值 }
; - var fn=p=>{ return p };
- var fn=()=>{ return "我没有参数" };
- var fn=(n,m)=>{ return n+m };
- var fn=(name,age)=>{ return { name1:name,age1:age } }返回值为对象;
- 格式:
- 箭头函数中的this指向
- 箭头函数中的this指向与父级中的this指向相同
- 普通函数中的this指向,一般看函数调用时,点前面是谁,this指向谁;
<script> var fn=()=>{ console.log("外面的this:"+this);//打印结果为:外面的this:[object Window] return { //普通函数 getThis:function () { console.log("里面的this:"+this);//this指向fn }, //es6中普通函数的简写 getThis1() { console.log("里面的this:"+this);//this指向fn }, //箭头函数 getThis2:()=>{ console.log("里面的this:"+this);//this指向fn中的this,是window; } } }; var obj=fn(); obj.getThis();//结果为:里面的this:[object Object],即this指向点前面的对象 obj.getThis1();//结果为:里面的this:[object Object],即this指向点前面的对象 obj.getThis2();//结果为:里面的this:[object Window],即箭头函数this指向等于父级函数中的this; </script>
- 复习this指向
- 自执行函数中的this指向window;
- 回调函数中的this一般指向window;
- 函数调用执行时,点前面是谁,this指向谁,如果没有,指向window;
- 当遇到函数类原型上的方法call(),bind(),apply(),this指向会改变
- 当元素身上添加事件后,事件发生时,函数中的this指向当前元素
- 箭头函数中的this指向,与父级函数中的this指向相同;
2 class创建类
- 类的创建
- 类创建的表达式:
class 类名{ constructor(){ //写类的私有属性和方法,会继承给实例对象的私有属性和方法 } getName(){ //设置类原型上的属性和方法,即公有属性和方法 } static getAge(){ //设置类作为对象角色使用的私有属性,也叫类的静态属性,与实例对象的属性没有关系,二者相互独立 } } 类名.xxx=xxx;//设置类的静态属性;
- 类创建的代码实例:
<script> class F{ //1 构造函数写在constructor里面,constructor里面的属性和方法都是类私有的属性和方法 constructor(name,age){ this.name=name; this.age=age; } //2 如下设置,就设置在类的prototype原型上,为公有属性和方法; getName(){ console.log(this.name)//此时this指向实例对象 } //3 类静态属性方法的写法 static getAge(){ console.log(this.age);//此时this指向类对象,就是F作为对象角色时,身上的属性age; } } var f1=new F("xiehe",3); var f2=new F("guobin",26); console.log(f1.getName===f2.getName);//结果为true,比较两个实例上的getName地址是否一致,如果一致证明getName()在类函数的原型上,为公有方法; /*f1.getAge();//会报错:f1.getAge is not a function,说明getAge属性不是实例对象的属性;*/ F.getAge();//结果为undefined,因为F类对象没有静态属性age; F.age=30;//设置F类对象的静态属性; F.getAge();//结果为30,证明打印了F类对象上的静态属性age; </script>
3 类的继承
- 类的继承:
- 知识点:
- super会继承私有属性,还可以将S类的原型作为F类的实例,进而通过原型链来获取F类的原型上的属性方法,但是又区别于原型链继承,在之前的原型链继承中会存在两个问题,一为:子类的原型上会存在父类的私有属性,二为:子类原型上的constructor不存在了;但是super获取的子类S类原型上不存在父类F类的私有属性,而且constructor也是S类的属性
- 子级类函数的
__proto__
属性,指向父级类函数;即父级类函数在子级类函数的原型链上,则子类函数就可以通过原型链调用父类函数的静态属性;子类函数上不存在父类函数的静态属性;
- 类继承的表达式:
class S extends F{ //S类继承F类的私有属性及F类的实例对象及F类的静态属性 constructor(name,age,color){ super(name,age);//继承F类的私有属性方法,作为S类的私有属性方法,继承F类的实例,作为S类的原型,继承F类的静态属性,作为S类的静态属性; this.color=color; //设置S类自己的私有属性方法 } //设置S类自己的公有属性方法 getSex(){ alert(1);} //设置S类自己的静态属性 static getMan(){...}; }
- 类继承的实例:
<script> class F{ //1 构造函数写在constructor里面,constructor里面的属性和方法都是类私有的属性和方法 constructor(name,age){ this.name=name; this.age=age; } //2 如下设置,就设置在类的prototype原型上,为公有属性和方法; getName(){ console.log(this.name) } //3 类静态属性方法的写法 static getAge(){ console.log(this.age);//此时this指向类对象,就是F作为对象角色时,身上的属性age; } } //类的继承 class S extends F{ //S类继承F类的私有属性及F类的实例对象及F类的静态属性 constructor(name,age,color){ super(name,age);//既继承父类F类的私有属性,也将S类的原型作为F类的实例,进而通过__proto__来找到F类的原型,获取其公有属性方法,而且不存在原型链继承的两个问题; this.color=color;//设置自己S类的私有属性 } //设置S类自己的公有属性和方法 getSex(){ console.log("nan"); } //设置S类自己的静态属性 static getTime(){ console.log(this.time); } } var f1=new F("xiehe",3); F.age=100; F.getAge();//结果为100; var s1=new S("guobin",26,"red"); console.dir(f1); console.dir(s1); s1.getSex();//结果为:nan S.getAge();//结果为100;代表S类可以通过自身的原型链调用F类身上的静态属性; S.time=200; S.getTime();//结果为200; </script>
- 知识点:
4 增强的对象字面量及字符串模板
- 增强的对象字面量
- 知识点:
- 增强的对象字面量,即若对象中的属性名与属性值赋值相同,则可以写一个;
- 设置
__proto__:obj
,则将obj赋值到原型上;
<script> var obj={ name:"xiehe", age: 3 }; var obj1={ name:"xiehe", age: 3 }; var eat="pingguo"; var fn=p=>p; //增强的对象字面量,即若对象中的属性名与属性值赋值相同,则可以写一个; //设置__proto__:obj,则将obj赋值到原型上; var objOther={obj,eat,fn};//将obj作为自己的私有属性; var objOther2={__proto__:obj1,eat,fn};//将obj中的键值对作为自己原型上的属性; objOther.obj.name="guobin"; console.log(obj);//会将obj中的name改变; console.dir(objOther); objOther2.name="guobin"; console.log(obj1);//不会改变,只是在objOther2上添加了私有属性name; console.dir(objOther2); </script>
- 知识点:
- 字符串模板
- 知识点:字符串拼接时,用双撇,变量字符串添加在
${...}
中;
<script> var name="美好的一天"; console.log("今天是"+name);//结果为:今天是美好的一天; console.log(`今天是${name}`);//结果为:今天是美好的一天; </script>
- 知识点:字符串拼接时,用双撇,变量字符串添加在
5 解构赋值
- 定义:将对象身上的属性名解构出来,当使用时,直接使用属性名,就能拿到属性值,不用再使用对象点属性名获取;
- 表达式:
{属性名}=obj
; - 注意点:在对象中如果属性名为函数名,属性值为一个函数,被解构出来,调用函数时,函数中的this指向不再是对象,而是window;
<script> var objn={ name1:"xiehe", age:3, showName(){ console.log("this指向为:"+this) } }; var {name1,age,showName}=objn; console.log(name1);//结果为:xiehe console.log(age);//结果为3; showName();//结果为:this指向为:[object Window] objn.showName();//结果为:this指向为:[object Object] var {alert}=window;//从window对象上解构出alert属性; alert(3);//弹出3 </script>
6 let和const
- var:for循环中如果用var来声明变量时,不会形成私有作用域,可以重复设置var,不会报错,但是已经声明过的不再声明,会重新赋值
- let:for循环中用let来设置,会形成私有作用域,里面的n是私有的n,不是全局n;所以全局不会变化;不能重复设置let,会报错,可以对变量重新赋值;
- const:设置的为一个常量,不是变量,不能进行更改
- 三者的不同
- var能进行预解释;而let和const不能进行预解释;
- var针对同一变量可以重复设置声明,而let不能重复设置声明,会报错,但可以重新赋值;
- let能形成一个块状作用域,与外界无关联;
- const设置的为一个常量,不能进行更改;
<script> //1 var 设置 var n=10; for(var i=0; i<5; i++){ var n=20; } console.log(n);//得到的值为20; //总结:for循环中如果用var来声明变量时,不会形成私有作用域,可以重复设置var,不会报错,但是已经声明过的不再声明,会重新赋值 //2 let设置 let n=10; for(let i=0; i<5; i++){ let n=20; //let n=30;不能重复设置let; console.log(n);//得到的值为20; } console.log(n);//得到的值为10; //总结:for循环中用let来设置,会形成私有作用域,里面的n是私有的n,不是全局n;所以全局不会变化;不能重复设置let,会报错; //3 const设置 const n=20; n=30;//此时会报错 console.log(n); //总结:const设置的为一个常量,不是变量,不能进行更改 </script>
7 箭头函数中的形参
- 设置默认的形参值:
var fn=(a=3,b=5)=>{ console.log(a+b) }
- 箭头函数中如果没有传实参则按着默认值执行,如果传入实参,按照实参值执行;
<script> var fn=(a=12,b=5)=>{ console.log(a+b); }; fn();//结果为17; fn(10,30);//结果为40; </script>
- 形参
...keys
设置,代表除了固定形参,其余的所有的实参值;- 箭头函数中不能用arguments获取实参值
- 设置
...keys
后,在函数内获取剩下的实参时用keys,不加点;
<script> var fn=(a,b,...keys)=>{ console.log(`第一个参数为:${a}`); console.log(`第二个参数为:${b}`); console.log(`剩下的参数为:${keys}`);//此时直接用keys; }; fn("tian","kong","fen","wai","lan"); /*打印结果为: * 第一个参数为:tian *第二个参数为:kong * 剩下的参数为:fen,wai,lan * */ fn("tian"); /*打印结果为: * 第一个参数为:tian * 第二个参数为:undefined * 剩下的参数为:空 * */ </script>
8 扩展运算符
-
...数组名
代表数组中的所有元素可以当成参数依次传入,与apply相似;<script> var ary=[29,12,22]; var ary1=[11,20,...ary]; console.log(ary1);//结果为:[11, 20, 29, 12, 22] var Max=Math.max(...ary1);//求最大值传入实参; console.log(Max);//打印29; </script>
9 运动实例
- 代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>运动实例</title> <style> div{ width: 60px; height: 60px; border-radius: 50%; margin-bottom: 10px; } .div1{ background-color: red; } .div2{ background-color: green; } .div3{ background-color: yellow; } </style> </head> <body> <div class="div1" style="margin-left:0"></div> <div class="div2" style="margin-left:0"></div> <div class="div3" style="margin-left:0"></div> <script> var oDiv1=document.getElementsByTagName("div")[0]; var oDiv2=document.getElementsByTagName("div")[1]; var oDiv3=document.getElementsByTagName("div")[2]; //ele:操作的元素;target:元素运动到的目的地;callback:到达目的地要干什么; function add(ele,target,callback) { setTimeout(function () { var n=parseFloat(ele.style.marginLeft); if(n===target){ callback(); }else if(n<target){ n++; ele.style.marginLeft=n+"px"; add(ele,target,callback); }else{ n--; ele.style.marginLeft=n+"px"; add(ele,target,callback); } },10); //利用setInterval实现 /*var timer=setInterval(function () { var n=parseFloat(ele.style.marginLeft); if(n===target){ clearInterval(timer); callback(); }else if(n<target){ n++; ele.style.marginLeft=n+"px"; }else{ n--; ele.style.marginLeft=n+"px"; } },10);*/ } add(oDiv1,100,function () { add(oDiv2,200,function () { add(oDiv3,300,function () { add(oDiv3,150,function () { add(oDiv2,150,function () { add(oDiv1,150,function () { alert("运动结束"); }) }) }) }) }) }) </script> </body> </html>