《深入理解ES6》笔记

160 阅读2分钟

深入理解ES6

三、函数

1.默认参数值对arguments的影响

在ES5非严格模式下参数的改变会同步到arguments对象中

function test(name,age) {
  console.log(name===arguments[0]); //true
  console.log(age===arguments[1]); //true
  name='张三';
  age=12;
  console.log(name===arguments[0]); //true
  console.log(age===arguments[1]); //true
}
test('李四',10);

在ES5严格模式下则会输出
true
true 
false
false

在ES6中无论是否指定严格模式,都与ES5严格模式相同。

function test(name,age=18) {
  console.log(arguments.length);
  console.log(name===arguments[0]);
  console.log(age===arguments[1]);
  name='张三';
  age=12;
  console.log(name===arguments[0]);
  console.log(age===arguments[1]);
}
test('李四');

输出
1
true
false
false
false

这样总是可以通过arguments对象将参数恢复为默认值。

2.不定参数

function test(name,...args) {
  console.log(name); // 李四
  console.log(args); // [18, "man"]
}
test('李四',18,'man');
  • 不可以在setter中使用。
  • 无论是否使用不定参数,arguments对象总是包含所有传入对象的参数。

3.展开运算符

var value=[2,3,6,32,-1,-200];
console.log( Math.max.apply(Math,value) ); //32

因为Math.max(1,2,.......)可以传递不限定参数并返回最大的一个,但是不支持传递数组,所以借助Array原型链上的apply方法的第二个参数来实现传递数组的目的。

ES6的展开运算符可以简化上述事例

var value=[2,3,6,32,-1,-200];
console.log(Math.max.apply(Math,value)); //32
console.log(Math.max(...value)); //32
value=[-12,-294,-29,-49]
console.log(Math.max(...value,0)); //0  限定最小值

3.明确函数的多种用途

1.关于函数的new操作

function Test(name) {
  this.name=name;
}
console.log(new Test('张三'));   // [Object Object]
console.log(Test('张三'));      // undefined
console.log(name);      //张三

不同过new调用Test,会返回undefined,在非严格模式下还会创建一个全局变量

JS函数有两个内部方法[call]和[constructor]

  • 通过new关键字调用函数时执行[constructor]函数时
  1. 创建一个实例对象
  2. 绑定this到此对象上
  3. 执行函数体
  4. 返回此对象
  • 不同过new调用函数时执行[call]函数,直接执行函数体 箭头函数没有[constructor]方法

2.在es5中判断函数被调用的方式

function Person(name) {
  if(this instanceof Person) {
    this.name=name;
  }else {
    throw new Error('请用new调用函数')
  }
}

const person=new Person('jack');
const person=Person('jack');  // error

此方式有缺陷,如
const person=Person.call(person,'jack');  // 有效
这种情况函数调时无法分辨是否使用new关键字

3.元属性 new.target

es6引入new.target元属性(☞非对象的属性),当调用函数的[construtor]方法时被赋值为构造函数,若调用[call]则被赋值为undefined

function Person(name) {
  console.log(new.target); // 1.使用new关键字 new.target=Person 2.直接调用  new.target=undefined 
  if(new.target===Person) {
    this.name=name;
  }else {
    throw new Error('请用new调用函数')
  }
}

const person=new Person('jack');
const person2=Person('jack');  // error
Person.call(person,'jack');// error

不能在函数外使用new.target