JavaScirpt之apply&call和bind

一.call()和 apply()概念和區別

1.概念javascript

在 javascript 中,call 和 apply 都是爲了改變某個函數運行時的上下文(context)而存在的,換句話說,就是爲了改變函數體內部 this 的指向。java

2.區別es6

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 的真正的用武之地,他們真正強大的地方是可以擴充函數賴以運行的做用域app

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()後會建立一個新的函數,而且不會自動執行,須要調用執行this

//經過這個例子看一下三者的區別
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 則是當即調用;
相關文章
相關標籤/搜索