this, bind, call, apply interview questions

Know this, what do bind, call and apply specifically refer to

They are all functional methods

call: Array.prototype.call(this, args1, args2]) apply: Array.prototype.apply(this, [args1, args2]): Before ES6, used to expand the array call foo.appy(null, []),, after ES6, use the ... operator

  • New binding> explicit binding> implicit binding> default binding
  • If you need to use bind's currying and apply's array destructuring, bind to null, use Object.create(null) as much as possible to create a DMZ object

Four rules:

  • Default binding, no other decorations (bind, apply, call), defined in non-strict mode to point to the global object, defined in strict mode to point to undefined
function foo() {
 	console.log(this.a); 
}

var a = 2;
foo();
  • Implicit binding: Whether there is a context object at the call location, or whether it is owned or contained by an object, then the implicit binding rule will bind this in the function call to this context object. Moreover, only the upper layer or the last layer of the object attribute chain has a role in the calling position
function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
  foo: foo,
}

obj.foo(); // 2
  • Display binding: display the binding this by running call and apply on the function
function foo() {
  console.log(this.a);
}

var obj = {
  a: 2
};

foo.call(obj);

Hard binding of display binding

function foo(something) {
  console.log(this.a, something);
  
  return this.a + something;
}

function bind(fn, obj) {
  return function() {
    return fn.apply(obj, arguments);
  };
}

var obj = {
  a: 2
}

var bar = bind(foo, obj);

New binding, new calling a function will create a brand new object and bind this object to the this of the function call.

  • When New is bound, if it is a hard-bound function of new, then this hard-bound this will be replaced with the new object created by new.
function foo(a) {
  this.a = a;
}

var bar = new foo(2);
console.log(bar.a)

(4) Question: handwritten bind, apply, call

// call

Function.prototype.call = function (context, ...args) {
  context = context || window;
  
  const fnSymbol = Symbol("fn");
  context[fnSymbol] = this;
  
  context[fnSymbol](...args);
  delete context[fnSymbol];
}
// apply

Function.prototype.apply = function (context, argsArr) {
  context = context || window;
  
  const fnSymbol = Symbol("fn");
  context[fnSymbol] = this;
  
  context[fnSymbol](...argsArr);
  delete context[fnSymbol];
}
// bind

Function.prototype.bind = function (context, ...args) {
  context = context || window;
  const fnSymbol = Symbol("fn");
  context[fnSymbol] = this;
  
  return function (..._args) {
    args = args.concat(_args);
    
    context[fnSymbol](...args);
    delete context[fnSymbol];   
  }
}
    



// MDN的标准源码
if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis || window,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

 

 

Test test:

Function.prototype.myCall = function (context) {console.log('this',this)}
var obj = {a:1}

aaa.myCall(obj)

// 输出
// this ƒ aaa(obj){alert(obj)}

 

Guess you like

Origin blog.csdn.net/lianjiuxiao/article/details/114886697