call、apply、bind三者的用法和區別
阿新 • • 發佈:2019-01-31
1. call
call、apply、bind都是改變this指向的方法
- fn.call
當前例項(函式fn)通過原型鏈的查詢機制,找到
function.prototype
上的call
方法,function call(){[native code]}
- fn.call()
把找到的
call
方法執行
當call
方法執行的時候,內部處理了一些事情
1.首先把要操作的函式中的this關鍵字變為call
方法第一個傳遞的實參
2.把call
方法第二個及之後的實參獲取到
3.把要操作的函式執行,並且把第二個以後傳遞進來的實參傳遞給函式
fn.call([this],[param]...)
- call中的細節
- 非嚴格模式
如果不傳引數,或者第一個引數是
null
或nudefined
,this
都指向window
let fn = function(a,b){
console.log(this,a,b);
}
let obj = {name:"obj"};
fn.call(obj,1,2); // this:obj a:1 b:2
fn.call(1,2); // this:1 a:2 b:undefined
fn.call(); // this:window a:undefined b:undefined
fn.call(null); // this=window a=undefined b=undefined
fn.call(undefined); // this=window a=undefined b=undefined
- 嚴格模式
第一個引數是誰,this就指向誰,包括null和undefined,如果不傳引數this就是undefined
"use strict"
let fn = function(a,b){
console.log(this,a,b);
}
let obj = {name:"obj"};
fn.call(obj,1,2); // this:obj a:1 b:2
fn.call(1,2); // this:1 a:2 b=undefined
fn.call(); // this:undefined a:undefined b:undefined
fn.call(null); // this:null a:undefined b:undefined
fn.call(undefined); // this:undefined a:undefined b:undefined
2. apply
- apply:和call基本上一致,唯一區別在於傳參方式
apply把需要傳遞給fn的引數放到一個數組(或者類陣列)中傳遞進去,雖然寫的是一個數組,但是也相當於給fn一個個的傳遞
fn.call(obj, 1, 2);
fn.apply(obj, [1, 2]);
3. bind
- bind:語法和call一模一樣,區別在於立即執行還是等待執行,bind不相容IE6~8
fn.call(obj, 1, 2); // 改變fn中的this,並且把fn立即執行
fn.bind(obj, 1, 2); // 改變fn中的this,fn並不執行
this改變為obj了,但是繫結的時候立即執行,當觸發點選事件的時候執行的是fn的返回值undefined
document.onclick = fn.call(obj);
bind會把fn中的this預處理為obj,此時fn沒有執行,當點選的時候才會把fn執行
document.onclick = fn.bind(obj);