每个函数都包含两个非继承而来的方法:call()方法和apply()方法。
一、call/apply/bind方法的来源
call,apply,bind 这三个方法其实都是继承自Function.prototype中的,属于实例方法
console.log(Function.prototype.hasOwnProperty('call')) //true
console.log(Function.prototype.hasOwnProperty('apply')) //true
console.log(Function.prototype.hasOwnProperty('bind')) //true
二、 Function.prototype.call()
call是function才有的,call就是调用一个函数,和()括号运算符不一样的是,call可以改变function的上下文,就是内部的this的指向,然后在所指定的作用域中,调用该函数。并且会立即执行该函数。
window.color = 'red';
document.color = 'yellow';
var s1 = {color: 'blue' };
function changeColor(){
console.log(this.color);
}
changeColor.call(); //red (默认传递参数)
changeColor.call(window); //red
changeColor.call(document); //yellow
changeColor.call(this); //red
changeColor.call(s1); //blue
1. call()方法可以传递两个参数。
第一个参数是指定函数内部中this的指向(也就是函数执行时所在的作用域),第二个参数是函数调用时需要传递的参数。
function keith(a, b) {
console.log(a + b);
}
keith.call(null, 1, 2); //3
2. call方法的一个应用是调用对象的原生方法。也可以用于将类数组对象转换为数组。
代码中,hasOwnProperty是obj对象继承的方法,如果这个方法一旦被覆盖,就不会得到正确结果。call方法可以解决这个方法,它将hasOwnProperty方法的原始定义放到 obj 对象上执行,这样无论obj上有没有同名方法,都不会影响结果
var obj = {};
console.log(obj.hasOwnProperty('toString')); //false
// 覆盖hasOwnProperty方法,使它不可用🚫
obj.hasOwnProperty = function() {
return true;
}
console.log(obj.hasOwnProperty('toString')); //true
console.log(Object.prototype.hasOwnProperty.call(obj, 'toString')); //false