call,apply,bind方法使用

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

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

  • 用于动态改变函数运行时,函数内容的this指向,和传入参数值。

fun.bind(thisArg, arg1,arg2)

  • bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
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)))
    }
}

你可能感兴趣的:(call,apply,bind方法使用)