call
使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。(call() 方法接受的是一个参数列表)
function.call(thisArg, arg1, arg2, ...) // thisArg为要传的this值,没有时用undefined或null占位
- 使用 call 方法调用父构造函数
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);
- 使用 call 方法调用匿名函数
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调用匿名函数
}
- 使用 call 方法调用函数并且指定上下文的 'this'
var obj = {
animal: 'cats', sleepDuration: '12 and 16 hours'
};
function greet(){
var reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' ');
console.log(reply);
}
greet.call(obj); //"cats typically sleep between 12 and 16 hours"
- 使用 call 方法调用函数并且不指定第一个参数(argument)
var sData = 'marshall';
function display(){
console.log("sData's value is %s",this.sData);
}
display.call(); // sData value is marshall
在严格模式下,this 的值将会是undefined
var sData = 'marshall';
function display(){
console.log("sData's value is %s",this.sData);
}
display.call(); // Cannot read the property of 'sData' of undefined
apply
调用一个具有给定 this 值的函数,以及以一个数组(或一个类数组对象)的形式提供的参数。 (apply() 方法接受的是一个包含多个参数的数组。)
apply(thisArg, argsArray) // thisArg为this的值, argsArray为数组或类数组对象
- 使用apply和内置函数 对于一些需要写循环以遍历数组各项的需求,我们可以用apply完成以避免循环。
//找出数组中最大值和最小值
var numbers = [5, 6, 2, 3, 7];
//使用Math.min和Math.max以及apply函数时的代码
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);
上边这种调用apply的方法,有超出JavaScript引擎参数长度上限的风险。 如果我们的参数数组非常大,推荐使用下边这种混合策略:将数组切块后循环传入目标方法
function minOfArray(arr) {
var min = Infinity;
var QUANTUM = 32768;
for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
min = Math.min(submin, min);
}
return min;
}
var min = minOfArray([5, 6, 2, 3, 7]);
bind
bind()函数会创建一个新的绑定函数,这个绑定函数包装了原函数的对象。调用绑定函数通常会执行包装函数。 使用 bind 可以让 this 不被改变
function f1(p1, p2){
console.log(this, p1, p2)
}
let f2 = f1.bind({name:'frank'}) // f2 就是 f1 绑定了 this 之后的新函数
f2() // 等价于 f1.call({name:'frank'})
bind 还可以绑定其他参数
let f3 = f1.bind({name:'frank'}, 'hi')
f3() // 等价于 f1.call({name:'frank'}, hi)