每個函數都包含兩個非繼承而來的方法: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