JavaScript中的call、apply

JavaScript中的call、apply

call

JavaScript中的call是调用一个函数,在调用函数时,将this的值绑定为call参数中的第一个参数。

var bye = function(param, param2){
    console.log(this);
    console.log(param);
    console.log(param2);
    console.log("bye");
    console.log(this.x)
}

t = {‘x‘: 1};

bye.call(t, 1, 2);

其结果为:

Object {x: 1}
1
2
bye
1

当然,我们也可以将this值绑定为一个原始值,调用上述函数:

bye.call(5, 1, 2);

其结果为:

Number {[[PrimitiveValue]]: 5}
1
2
bye

在non-strict 模式下,如果我们将null,undefined和原始类型的值传给this参数,其this值将被global代替,在MDN中有这样的说明:

thisArg
The value of this provided for the call to fun. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode code, null and undefined will be replaced with the global object, and primitive values will be boxed.

call函数的作用就是我们在调用方法时可以设定一个不同的对象,因为其默认的对象就是当前对象,正因为这样,我们可以只写一次该方法,在另一对象中继承该方法,然后调用它,而不需要再写一遍该方法。MDN中对该方法的介绍:

You can assign a different this object when calling an existing function. this refers to the current object, the calling object. With call, you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.

应用场景一:利用call实现继承(Using call to chain constructors for an object)

function Product(name, price) {
  this.name = name;
  this.price = price;

  if (price < 0) {
    throw RangeError(‘Cannot create product ‘ +
                      this.name + ‘ with a negative price‘);
  }

  return this;
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = ‘food‘;
}

Food.prototype = Object.create(Product.prototype);

function Toy(name, price) {
  Product.call(this, name, price);
  this.category = ‘toy‘;
}

Toy.prototype = Object.create(Product.prototype);

var cheese = new Food(‘feta‘, 5);
var fun = new Toy(‘robot‘, 40);

Food和Toy利用call继承了Product的name和price,然后各自又有了category 属性。

应用场景二:利用call调用匿名函数(Using call to invoke an anonymous function)

var animals = [
  { species: ‘Lion‘, name: ‘King‘ },
  { species: ‘Whale‘, name: ‘Fail‘ }
];

for (var i = 0; i < animals.length; i++) {
  (function(i) {
    this.print = function() {
      console.log(‘#‘ + i + ‘ ‘ + this.species
                  + ‘: ‘ + this.name);
    }
    this.print();
  }).call(animals[i], i);
}

apply

apply与call几乎完全相同,只是在传递参数时apply传递的是数组(array)或者是类似数组的对象( array-like object),其调用方式:

fun.apply(this, [‘eat‘, ‘bananas‘]);
fun.apply(this, new Array(‘eat‘, ‘bananas‘));

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。