**Function.prototype.call()
接收若干个参数列表,fn.call(thisArg,arg1,arg2,….);而apply()除了第二个参入参数的方式不同以外,几乎类似apply()接收的是一个包含多个参数的数组,fn.apply(thisArg,[argsArray])
用法:fn.call(obj);动态绑定this的指向,把this变为我们想要的对象,用制定的对象调用fn
**
参数问题:
1、两者this:
this不一定就是该函数执行时真正的this值,在非严格模式下,如果this的值为null或者undefined,则this指向浏览器全局对象window(node下为global),同时值为原始值(数字、字符串,布尔值)的this会指向原始值的包装对象
2 、fn.apply(thisArg,[argsArray])
一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。
简单测试一下
function fn() {
console.log(1);
return this
}
var a={};
var b=null;
var c=undefined;
var str="test";
console.log(fn.call(a));//this=>{}
console.log(fn.call(b));//this=>window
console.log(fn.call(c));//this=>window
console.log(fn.call(str));
//this=>String {0: "t", 1: "e", 2: "s", 3: "t", length: 4, [[PrimitiveValue]]: "test"} //包装对象
当this不是我们想要的时,就可以用call()中的对象替换来调用函数,最常用的就是用另一个对象调用构造函数中的方法
看看MDN中的例子
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';
}
//function Toy 同上
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);
console.log(cheese);//{name: "feta", price: 5, category: "food"}
console.log(fun);//{name: "robot", price: 40, category: "toy"}
使用call()方法调用匿名函数
摘自MDN:创建了一个匿名函数,然后通过调用该函数的call方法,将每个数组元素作为指定的this值执行了那个匿名函数。这个匿名函数的主要目的是给每个数组元素对象添加一个print方法,这个print方法可以打印出各元素在数组中的正确索引号。
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);
}
使用call方法调用函数并且指定上下文的’this’
在下面的例子中,当调用 greet 方法的时候,该方法的 this 值会绑定到 i 对象。
function greet() {
var reply = [this.person, 'Is An Awesome', this.role].join(' ');
console.log(reply);
}
var i = {
person: 'Douglas Crockford', role: 'Javascript Developer'
};
greet.call(i); // Douglas Crockford Is An Awesome Javascript Developer