Skip to content

call、apply、bind

发表于
更新于
阅读量

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.把要操作的函数执行,并且把第二个以后传递进来的实参传递给函数

javascript
fn.call([this],[param]...)

如果不传参数,或者第一个参数是nullnudefinedthis都指向window

javascript
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

手写call

javascript
Function.prototype.call = function(object){
    object = object || window
    let fn = Symbol(object)
    object[fn] = this
    let arg = [...arguments]
    object[fn](...arg)
    delete object[fn]
}

apply

基本用法

和call基本上一致,唯一区别在于传参方式

apply把需要传递给fn的参数放到一个数组(或者类数组)中传递进去,虽然写的是一个数组,但是也相当于给fn一个个的传递

javascript
fn.call(obj, 1, 2);
fn.apply(obj, [1, 2]);

手写apply

javascript
Function.prototype.apply = function(object){
    object = object || window
    let fn = Symbol(object)
    object[fn] = this
    let arg = [...arguments]
    object[fn](...arg)
    delete object[fn]
}

bind

基本用法

语法和call一模一样,区别在于立即执行还是等待执行

javascript
fn.call(obj, 1, 2); // 改变fn中的this,并且把fn立即执行
fn.bind(obj, 1, 2); // 改变fn中的this,fn并不执行

this改变为obj了,但是绑定的时候立即执行,当触发点击事件的时候执行的是fn的返回值undefined

手写bind

javascript
Function.prototype.bind = function(object){
    let self = this
    let arg = [...arguments]
    return function(){
        let newarg = [...arguments]
        return self.apply(object,arg.concat(newarg))
    }
}

Released under the MIT License.