JS笔记《函数扩展》

96 阅读3分钟

参数默认值

  • 使用参数默认值时,函数不能有同名参数,会报错。
function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello
  • 参数变量是默认声明的,在函数体内,不能用letconst再次声明,否则会报错。
function foo(x = 5) {
  let x = 1;  // SyntaxError: Identifier 'x' has already been declared
}

与解构赋值结合使用

function foo({x, y = 5}) {
  console.log(x, y);
}

foo({})           // undefined 5
foo({x: 1})       // 1 5
foo({x: 1, y: 2}) // 1 2
foo()             // TypeError: Cannot read property 'x' of undefined
  • 双重默认值。
// 调用时没传参数,采用默认参数{ a: 'hello' }
// 从默认参数中解构 a = hello, b没有,采用默认值 world
function f({ a, b = 'world' } = { a: 'hello' }) {
  console.log(b);
}

f() // world

rest参数

  • 用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是数组,该变量将多余的参数放入数组中。只能是最后一个参数,否则报错。
function add(a, b, ...values) {
    console.log(values) // [3, 4, 5]
}
add(1,2,3,4,5)

严格模式

  • 只要函数参数使用了默认值、解构赋值、扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。
// 报错
function doSomething(a, b = a) {
  'use strict';
  // code
}

// 报错
const doSomething = function ({a, b}) {
  'use strict';
  // code
};

// 报错
const doSomething = (...a) => {
  'use strict';
  // code
};

箭头函数

用法

var f = v => v;

// 等于:
var f = function (v) {
  return v;
};

// 如果箭头函数不需要参数或需要多个参数,使用()
var sum = (num1, num2) => num1 + num2;
// 等同于:
var sum = function(num1, num2){
    return num1 + num2;
}

// 如果箭头函数的代码块多于一条语句,要使用{}包起来,并使用 return返回
var sum = (num1, num2) => { 
    return num1 + num2; 
}

// 如果要返回对象,需要添加()包起来,否则会报错
let getTempItem = id => ({ id: id, name: "Temp" });

注意点

  • 箭头函数没有自己的this对象。

  • 不能使用call、apply、bind修改this指向。

  • 不可以当作构造函数,也就是不可以对箭头函数使用new命令。

  • 不可以使用arguments对象,该对象在函数体内不存在。使用rest参数替代。

  • 没有原型prototype

  • 不可以使用yield命令,因此箭头函数不能用作Generator函数。

this指向

  • 箭头函数中的this是定义函数的时候绑定,而不是在执行函数的时候绑定。 箭头函数根本没有自己的this,导致内部的this就是外层作用域的this(好比是变量,按照作用域链查找)。正是因为它没有this,所以也就不能用作构造函数。
var x = 11; 
var obj = { 
    x:22, 
    say:() => { 
        console.log(this.x); 
    }
}
obj.say(); // 11
// 普通函数的情况下,obj调用的say方法,this会指向obj
// 箭头函数的情况下,箭头函数中没有this,向上查找,外层this指向的是全局,所以调用时this指向的就是全局

this实战

var name = 'window';
    
function Person(name){
  this.name = name;
  this.obj = {
    name: 'obj',
    foo1: function(){
      return function (){
        console.log(this.name)
      }
    },
    foo2: function(){
      return () => {
        console.log(this.name)
      }
    }
  }
}

var person1 = new Person('person1')
var person2 = new Person('person2')

// 取到foo1函数的返回值,然后默认调用,this指向window
person1.obj.foo1()();  // window

// foo1函数通过call显示绑定调用,foo1中的this指向perosn2,
// 然后默认调用foo1返回的函数,this指向window
person1.obj.foo1.call(person2)(); // window

// 执行foo1函数获取返回的函数,然后通过显示绑定调用返回函数
person1.obj.foo1().call(person2);  // person2

// 取到foo2函数的返回值,然后默认调用,
// 由于是箭头函数,外层作用域的this指向的是obj
person1.obj.foo2()() // obj

// foo2函数通过call显示绑定调用,foo2中的this指向person2,执行返回函数,
// 由于是箭头函数,所以this指向perons2
person1.obj.foo2.call(person2)()  // person2

// 取到foo2函数的返回值,然后通过显示绑定调用返回函数,
// 由于是箭头函数,绑不绑定都没用,this依然指向obj
person1.obj.foo2().call(person2)   // obj