轉載自 https://www.cnblogs.com/tinkbell/p/3200488.htmljavascript
定義:html
call, apply是函數的方法, 只有函數纔有這2個方法.
做用:java
call, apply主要做用是改變函數賴以執行的做用域, 簡言之就是改變函數中this的指向.
用法:jquery
fn.call(obj, args1, args2, ...); //obj是指定函數賴以執行的對象, arg1等是傳給函數的參數(假若有的話)
fn.apply(obj, [args1, args2, ...]); //obj是指定函數賴以執行的對象, [arg1, ...]等是傳給函數的參數數組(假若有的話)數組
差異:app
call和apply的差異就是參數的不一樣.
call中的參數必須是一個個枚舉出來的.
apply中的參數必須是數組或者是arguments對象函數
// 例子1: function fn(arg){ alert(arg); } fn.call(this, 'hello world'); //hello world, 因爲fn中沒指定this, 因此此時的this指向window對象. fn.apply(this, ['hello world']); //hello world, 因爲fn中沒指定this, 因此此時的this指向window對象. // 例子2: function fn(arg1, arg2, arg3){ alert(arg1 + arg2 + arg3); } fn.call(this, 'hello world', 'petty', 'jack'); //hello worldpettyjack fn.apply(this, ['hello world', 'petty', 'jack']); //hello worldpettyjack // 例子3: function myFn(arg1, arg2, arg3){ alert(arg1 + arg2 + arg3); } function fn(arg1, arg2, arg3){ myFn.apply(this, arguments); //此處傳arguments對象, 即fn中的[arg1, arg2, arg3] } fn('hello', 'world', '!'); //helloworld! // 例子4: var o = { name: 'tom' }; function fn(){ alert(this.name); } fn.call(this); //此時this指向window, 因此是window的name值 fn.call(o); //此時this指向o, 因此是o的name值, 'tom' fn.apply(o); //同上 // 例子5: function MyFn(name){ this.name = name; } // 定義一個構造函數 function Fn(age, name){ this.age = age; MyFn.call(this, name); // 理解了call的定義後, 就不難看出, 此處繼承了MyFn的name屬性. //MyFn.apply(this, [name]); // 也可 } // 定義另外一個構造函數 var person = new Fn(20, 'tom'); alert(person.name); // 本來Fn是沒有name屬性的, 可是使用了call或者apply後, 就繼承了MyFn的name屬性, 因此爲'tom' // 理解了以上的call和apply的原理後, 咱們一塊兒來模仿jquery中each函數. function each(obj, fn){ var i; if(Object.prototype.toString.call(obj) === '[object Array]'){ for(i = 0, length = obj.length; i < length; i++){ fn.call(obj[i], i, obj[i]); } } else if(typeof obj === 'object'){ for(i in obj){ if(obj.hasOwnProperty(i)){ fn.call(obj[i], i, obj[i]); } } } else{ return false; } } var oDiv = document.getElementsByTagName('div'); each(oDiv, function(){ this.style.background = '#ff0000'; // 全部div的背景都變爲紅色的了. });