call,apply,bind方法使用

2019-07-16  本文已影响0人  焦糖大瓜子

fun.call(thisArg, arg1, arg2, ...)

fun.apply(thisArg, [arg1, arg2], ...)

fun.bind(thisArg, arg1,arg2)

var module = {
  x: 42,
  getX: function() {
    console.log('this', this)
    return this.x;
  }
}

var unboundGetX = module.getX;

console.log(module.getX)  // 直接是对函数的引用, this没有指定,this 为 window
console.log(module.getX()) // 使用对象module调用函数,所以this就是module
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined

var boundGetX = unboundGetX.bind(module);  
console.log(boundGetX());
// expected output: 42

bind VS call/apply

  1. 一个函数被 call/apply 的时候,会直接调用
  2. bind 会创建一个新函数
    当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。

使用apply实现bind


  Function.prototype.bind = function(context) {
    if(typeof this !== "function"){
       throw new TypeError("not a function");
    }
    let self = this;
    let args = [...arguments].slice(1); // args是arguments删除了第一参数的
    function Fn() {};
    Fn.prototype = this.prototype;

    // 新定义了一个bound方法
    let bound = function() {
        let arg = [...args, ...arguments]; //bind传递的参数和函数调用时传递的参数拼接
        context = this instanceof Fn ? this : context || this; // 判断执行上下文
        return self.apply(context, arg );
    }
    //原型链
    bound.prototype = new Fn();
    return bound;
}

var name = 'Jack';
function person(age, job, gender){
    console.log(this.name , age, job, gender);
}

var Pony = {name : 'Pony'};
let result = person.bind(Pony, 52, 'enginner')('male');

另一种简洁实现

Function.prototype._bind = function(){
    var self = this   //原函数
    var context = [].shift.call(arguments)  //this上下文
    var args = [].slice.call(arguments)  //参数
    return function(){
        self.apply(context, args.concat([].slice.call(arguments)))
    }
}
上一篇 下一篇

猜你喜欢

热点阅读