Front-end-learning-to-organize-notes icon indicating copy to clipboard operation
Front-end-learning-to-organize-notes copied to clipboard

this的原理,call,apply,bind的区别

Open Chocolate1999 opened this issue 4 years ago • 4 comments

Chocolate1999 avatar Jan 21 '21 09:01 Chocolate1999

都是改变this的指向,区别主要在于方法的实现形式和参数传递上的不同。call和apply方法都是在调用之后立即执行的。而bind调用之后是返回原函数,需要再调用一次才行 2、①:函数.call(对象,arg1,arg2....) ②:函数.apply(对象,[arg1,arg2,...]) ③:var ss=函数.bind(对象,arg1,arg2,....) 3、总结一下call,apply,bind方法: a:第一个参数都是指定函数内部中this的指向(函数执行时所在的作用域),然后根据指定的作用域,调用该函数。 b:都可以在函数调用时传递参数。call,bind方法需要直接传入,而apply方法需要以数组的形式传入。 c:call,apply方法是在调用之后立即执行函数,而bind返回函数,需要将函数再执行一遍。有点闭包的味道。

HearLing avatar Jan 22 '21 09:01 HearLing

JavaScript深入之call的模拟实现

Function.prototype.myCall = function (context = window) {
    // console.log(context); // foo
    context.fn = this;
    // console.log(this); // bar:function
    var arr = [...arguments];
    arr.shift();
    let result = context.fn(...arr);
    delete context.fn;
    return result;
}

// 测试一下
var foo = {
    value: 1
};

function bar(name, age) {
    console.log(name)
    console.log(age)
    console.log(this.value);
}

bar.myCall(foo, 'kevin', 18);
// kevin
// 18
// 1

Chocolate1999 avatar Jan 24 '21 12:01 Chocolate1999

JavaScript深入之apply的模拟实现

Function.prototype.myApply = function (context = window, arr) {
  context.fn = this;
  var result = context.fn(...arr);
  delete context.fn
  return result;
}

// 测试一下
var foo = {
  value: 1
};

function bar(name, age) {
  console.log(name)
  console.log(age)
  console.log(this.value);
}

bar.myApply(foo, ['kevin', 18]);
// kevin
// 18
// 1

Chocolate1999 avatar Jan 24 '21 12:01 Chocolate1999

JavaScript深入之bind的模拟实现

Function.prototype.myBind = function (context = window) {
  //判断调用者是否为函数
  if (typeof this !== 'function') {
    return new TypeError('Error');
  }
  //保存this调用方法的本身
  const that = this;
  //获取参数
  const args = Array.from(arguments).slice(1);
  //一个空函数,用来维护原型
  var tmp = function () { }
  let fn = function () {
    //由于返回一个函数,因此对于new fn();
    //不能改变this指向
    if (this instanceof fn) {
      return new that(...args, ...arguments);
    } else {
      return that.apply(context, args.concat(...arguments));
    }
  }
  //维护原型
  tmp.prototype = that.prototype;
  fn.prototype = new tmp();
  //返回函数
  return fn;
}
var foo = {
  value: 1,
};
function bar(name, age) {
  this.name = name;
  this.age = age;
  console.log(name);
  console.log(age);
  console.log(this.value);
}
let fn = bar.myBind(foo, 'Chocolate', 18);
fn();
console.log(foo);

// Chocolate
// 18
// 1
// { value: 1, name: 'Chocolate', age: 18 }

Chocolate1999 avatar Jan 24 '21 12:01 Chocolate1999