《深入理解ES6》之知识点记录
1,函数形参的默认值
function fn(url,timeout=2000,callback){}
- 解释:这里设置了第二个参数为2000,在这种情况先,不为第二个参数传入值或者主动为第二个参数传入undefined时,才会使用timeout的默认值
- 错误:之前会直接fn('/demo',,callback){}利用逗号的形式隔开,让其使用默认值,导致报错,即不能如此,而是要传入undefined
2,默认参数值对arguments对象的影响
//es5非严格模式
function fn(a){
console.log(arguments[0]===a)//true
a = 1;
console.log(arguments[0]===a)//true
}
fn(2,2)
//es5严格模式
function fn(a){
"use strict"
console.log(arguments[0]===a)//true
a = 1;
console.log(arguments[0]===a)//false
}
fn(2)
//es6
function fn(a,b=2) {
console.log(arguments.length)//1
console.log(a===arguments[0])//true
console.log(b===arguments[1])//false
a = 1;
console.log(a===arguments[0])//false
}
fn(1);//使用默认参数
function fn(a,b=2) {
console.log(arguments.length)//2
console.log(a===arguments[0])//true
console.log(b===arguments[1])//true
a = 1;
console.log(a===arguments[0])//false
}
fn(1,2);//使用命名参数
- es5非严格模式下:命名参数的变化会同步更新到arguments对象中
- es5严格模式下:命名参数的变化不会同步更新到arguments对象中
- es6使用默认参数下:arguments对象的行为同es5严格模式下一致;默认参数值存在使得arguments对象保持与命名参数分离
3,默认参数表达式
function getValue(){
return 1
}
function fn(a,b=getValue()){
return a+b
};
fn(1);//2
- 解释:b的默认参数为getValue方法执行后的返回值
function getValue(){
return 1
}
function fn(a,b=a){
return a+b
};
fn(1);//2
- 解释:默认参数是在函数调用时求值,所以可以使用先定义的参数作为后定义参数的默认值
4,不定参数
在函数的命名参数前添加三个点(...)就表明这是一个不定参数,该参数为一个数组
function fn(a,...b){}
fn(1,2,3,4)//则其中a为1,b为[2,3,4]
使用限制:
- 只能有一个不定参且只能写在末尾
- 不定参不能出现在对象字面量setter之中,之所以如此,是因为对象字面量setter的参数有且只能有一个
var obj = {
set name(...val){}//会报错,不能使用不定参
}
对arguments对象的影响:
- 无论是否使用不定参数,arguments对象总是包含所有传入函数的参数
5,展开运算符
展开运算符可以让你指定一个数组,并通过整合后的数组来访问,使用案例:
var arr = [1,2,3,4];
//求最大值
Math.max.apply(Math,arr);
Math.max(...arr);
Math.max(...arr,0);//限制Math.max返回的最小值为0
6,函数的name属性
见代码演示:
function a(){}
var b = function(){}
var c = function d(){}
var e = {
f:function(){}
}
console.log(a.name);//a
console.log(b.name);//b
console.log(c.name);//d
console.log(e.f.name);//f
- 普通的函数,name属性为声明时的函数名称
- 匿名函数表达式的name值为被赋值为该匿名函数的变量的名称
- 函数表达式有名字时,其名字比函数本身被复制的变量的权重要高
7,函数的多重用途
js函数里有两个不同的内部方法: [[Call]]和[[Construct]]
- 当通过new 关键字调用函数时,执行的是[[Construct]]函数,它负责创建一个通常被称为实例的新对象,然后再执行函数体,将this绑定到实例上;具有[[Construct]]的函数被称为构造函数,并不是所有的函数都有该方法,比如箭头函数就没有。
- 不通过new,则执行[[Call]]函数,从而直接执行代码中的函数体
如何判断函数是通过new关键字调用的呢?
元属性(new.target):
-
new.target为es6引入的元属性,是指非对象的属性,其可以提供非对象目标的补充信息(例如new)。
-
当调用函数的[[Construct]]方法时,new.target被赋值为new 操作符的目标,通常是新创建对象实例,也就是函数体内this的构造函数
-
当调用[[Call]]方法,则new.target的值为undefined
案例:
function Person(name) {
if(new.target !== undefined) {
this.name = name;
} else {
throw new Error(' 必须使用 new 生成实例 ');
}
}
// 另一种写法
function Person(name) {
if(new.target === Person) {
this.name = name;
} else {
throw new Error(' 必须使用 new 生成实例 ');
}
}
var person = new Person('狗蛋'); // 正确
var notAPerson = Person.call(person, ' 狗蛋 '); // 报错
使用: 可以利用new.target来限制类,比如,让某类不能被直接实例化使用,只能被继承使用,如下:
class Shape {
constructor() {
if(new.target === Shape) {
throw new Error('不可实例化');
}
}
}
class Rectangle extends Shape {
constructor(length, width) {
super();
}
}
var shape = new Shape(); // 报错
var rectangle = new Rectangle(10, 24); // 正确 此时new.target 为Rectangle
8,箭头函数
与传统函数的区别:
- 没有this,super,arguments和new.target绑定;箭头函数中的this,super,arguments及new.target这些值由外围最近一层非箭头函数决定
- 不能通过new关键字调用 箭头函数没有[[Construct]]方法;所以不能被用作构造函数,如果用new关键字调用箭头函数,会报错
- 没有原型;由于不可以通过new关键字调用箭头函数,因而没有构建原型的需求,所以箭头函数不存在prototype这个属性
- 不可以改变this的绑定;在函数的生命周期内始终保持一致
- 不支持arguments对象;箭头函数没有arguments绑定,所以你只能通过命名参数和不定参数两种形式访问参数,但是若箭头函数有外围函数,则他可以访问外围函数的arguments对象
- 不支持重复的命名参数;无论在严格模式下,箭头函数都不支持重复的命名参数,而在传统的函数规定中,只有在严格模式下才不能有重复的命名参数。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!