call,apply的使用及簡單實現

區別

call() 和 apply()的區別在於,call()方法接受的是若干個參數的列表,而 apply()方法接受的是一個包含多個參數的數組數組

var func = function(arg1, arg2) {};

func.call(this, arg1, arg2); // 使用 call,參數列表
func.apply(this, [arg1, arg2]); // 使用 apply,參數數組
複製代碼

使用場景

數組中最大值

var numbers = [5, 458, 120, -215];
Math.max.apply(Math, numbers); //458
Math.max.call(Math, 5, 458, 120, -215); //458

// ES6
Math.max.call(Math, ...numbers); // 458
複製代碼

驗證是不是數組

function isArray(obj){
    return Object.prototype.toString.call(obj) === '[object Array]';
}
isArray([1, 2, 3]);
// true

// 直接使用 toString()
[1, 2, 3].toString(); 	// "1,2,3"
"123".toString(); 		// "123"
123.toString(); 		// SyntaxError: Invalid or unexpected token
Number(123).toString(); // "123"
Object(123).toString(); // "123"

複製代碼

能夠經過 toString() 來獲取每一個對象的類型,可是不一樣對象的 toString()有不一樣的實現,因此經過 Object.prototype.toString() 來檢測,須要以 call() / apply() 的形式來調用,傳遞要檢查的對象做爲第一個參數。app

call實現

/** context 是改變this的目標對象,...args擴展符兼容多個參數 */
Function.prototype.myCall = function(context, ...args) {
  // 此處的 this,指向了 say 方法,打印的結果就是 [Function: say]
  let __ = (context[this.name] = this);
  __(...args);
};
複製代碼

看上去是否是挺簡單的,下面來試下這個方法ui

let Person = {
  name: "zhangsan",
  say(age, className) {
    console.log(`your name ${this.name}, age ${age}, className ${className}`);
  }
};

let Person1 = {
  name: "lisi"
};

// your name lisi, age 12, className class1
Person.say.myCall(Person1, 12, "class1");
複製代碼

apply實現

有了call的實現,apply 就簡單多了,就是參數的不一樣。this

Function.prototype.myApply = function(context, args) {
  let __ = (context[this.name] = this);
  __(args);
};
複製代碼

試下看看:spa

let Person = {
  name: "zhangsan",
  say(age, className) {
    console.log(
      `say your name ${this.name}, age ${age}, className ${className}`
    );
  },
  speak([age, className]) {
    console.log(
      `speak your name ${this.name}, age ${age}, className ${className}`
    );
  }
};

let Person1 = {
  name: "lisi"
};

// speak your name lisi, age 20, className class2
Person.speak.myApply(Person1, [20, "class2"]);
複製代碼

固然,這是一個簡單的處理,僅僅是爲了實現,提供了一個思路,爲了健壯性還缺乏對參數進行校驗等。prototype

相關文章
相關標籤/搜索