JavaScirpt之apply&call和bind
阿新 • • 發佈:2018-11-05
傳遞參數 sum string 合並 return 耦合 object pre ons
一.call()和 apply()概念和區別
1.概念
在 javascript 中,call 和 apply 都是為了改變某個函數運行時的上下文(context)而存在的,換句話說,就是為了改變函數體內部 this 的指向。
2.區別
call()和 apply()唯一區別在於傳參數,apply()接收兩個參數,一個是在其運行函數中的作用域,另外一個是參數數組其中,第二參數可以是 Array 的實例,也可以是 arguments 對象,call()第一個參數和 apply()一樣,第二個參數必須逐個列舉出來,通過代碼展示
function sum(num1, num2) { return num1 + num2; } function applySum(num1, num2) { console.log(arguments); //此時this對象是全局window對象 return sum.apply(this, arguments); // 或者 return sum.apply(this, [num1, num2]); } console.log(applySum(1, 2)); /** call()和apply()發放唯一區別在於傳參數.call()傳參數必須逐個列舉出來 */ function callSum(num1, num2) { console.log(...arguments); //此時this對象是全局window對象 return sum.call(this, num1, num2); // 或者使用ES6的語法 return sum.call(this, ...arguments); } console.log(callSum(1, 2));
3.傳遞參數並非 apply 和 call 的真正的用武之地,他們真正強大的地方是能夠擴充函數賴以運行的作用域
var o = { name: "kebi" }; window.name = "heyushuo"; function sayName() { console.log(this.name); } sayName.call(this); //heyushuo sayName.call(window); //heyushuo sayName.call(o); //kebi 此時函數的執行環境不一樣了,因為此時函數體內的this對象指向了o,於是結果顯示的是'kebi' //call和apply來擴充作用域的最大好處就是對象不需要與方法有任何耦合關系,
4.apply 和 call 的一些騷操作
//1.數組合並 var arr1 = [1, 2, 3]; var arr2 = ["heyushuo", "kebi"]; //arr1改變數組的作用域,arr2傳的參數 Array.prototype.push.apply(arr1, arr2); //[1,2,3,'heyushuo','kebi'] //或者 arr1.concat(arr2) // 或者ES6的語法 [...arr1, ...arr2]; //2.數組中的最大值 Math.max.apply(Math,arr1); //或者es6的語法 Math.max(...arr1); //3.判斷對象的數據類型 //在最原始的對象中進行,不能直接arr1.toString() 或者 o.tosString() 因為對象和數組已經把原始對象的toString()方法進行了修改 Object.prototype.toString.call(arr1); // [object Array] Object.prototype.toString.call(o)); //[object Object] //4.可以把偽數組變成真正的數組,例如 arguments / document.getElementsByTagName("span") Array.prototype.slice.call(document.getElementsByTagName("span"), 0)) //或者使用es6的語法 [...document.getElementsByTagName("span")]
二.bind()方法,ES5 提供了另外一個方法
解釋: bind()和 call,apply 的作用是一樣的,bind()這個方法會創建一個函數的實例,該方法可傳入兩個參數,第一個參數作為 this,第二個及以後的參數則作為函數的參數調用,這個方法和 call,apply 最重要的區別是,綁定 bind()後會創建一個新的函數,並且不會自動執行,需要調用執行
//通過這個例子看一下三者的區別
var o = {
name: "kebi"
};
window.name = "heyushuo";
function sayName() {
console.log(this.name);
}
sayName.call(window); //heyushuo
sayName.call(o); //kebi
sayName.apply(window); //heyushuo
sayName.apply(o); //kebi
//這是bind的用法
var objName = sayName.bind(o); //ie9+
objName(); //kebi
三.總結
- apply,call,bind 三者都是用來改變函數的 this 對象的指向的;
- apply,call,bind 三者都可以利用後續參數傳參;
- bind 是返回對應函數,便於稍後調用;apply,call 則是立即調用;
JavaScirpt之apply&call和bind