Record a knowledge point, mutual encouragement.

1. Simple use of call

Note the following two points when using the call method:

  1. The foo function itself executes
  2. Call changes the reference to this in function foo, which in this case points to obj
var obj = {
    value: 1
}
function foo() {
    console.log(this.value)
}
foo.call(obj)  // 1
Copy the code

2. Simulation implementation principle

Var obj = {value: 1, foo: function() {console.log(this.value)}Copy the code

Thus, the simulation principle is obtained:

1. Assign function foo to object obj

2. Call this function

3. Delete the function after the call

obj.fn = foo
obj.fn()
delete obj.fn
Copy the code

3. The first step

Call2 = Function (context) {context.fn = this context.fn() delete context.fn} value: 1 } function foo() { console.log(this.value) } foo.call2(obj) // 1Copy the code

4. The second step

The Call method accepts non-quantitative parameters

Use arguments inside a function to get an array of arguments classes

Array.tostring (); eval ();

Function.prototype.call2 = function (context) { context.fn = this const args = [] for(var i = 1, len = arguments.length;  i < len; i++) { args.push('arguments[' + i + ']'); } eval('context.fn(' + args + ')') delete context.fn} var obj = {value: 1 } function foo(name, age) { console.log(name) console.log(age) console.log(this.value) } foo.call2(obj, 'Tom', 18) // Tom // 18 // 1Copy the code

5. The third step

1. The first argument of the call method can be passed null, in which case this points to the window

2. The first parameter can also be passed as a constant, using the Object package layer

Function.prototype.call2 = function (context) {
    var context = context || window
    context.fn = this
    const args = []
    for(var i = 1, len = arguments.length; i < len; i++) {
        args.push('arguments[' + i + ']');
    }
    eval('context.fn(' + args + ')')
    delete context.fn
}
Copy the code

6. The fourth step

The Call method can have a return value

Function.prototype.call2 = function (context) {
    var context = context || window
    context.fn = this
    const args = []
    for(var i = 1, len = arguments.length; i < len; i++) {
        args.push('arguments[' + i + ']');
    }
    var res = eval('context.fn(' + args + ')')
    delete context.fn
    return res
}

var obj = {
    value: 1
}
function foo(name, age) {
    return {
        name, age, val: this.value
    }
}
console.log(foo.call(obj, 'Tom', 18))
// Object {
//    name: 'Tom',
//    age: 18,
//    value: 1,
// }
Copy the code

7. Simulation implementation of apply method

The implementation of Apply is similar to that of Call, except that the parameters received by Apply are passed in as an array

Function.prototype.apply2 = function (context, arr) { var context = context || window context.fn = this var res if (! arr) { res = context.fn() } else { var args = [] for(var i = 1, len = arguments.length; i < len; i++) { args.push('arguments[' + i + ']'); } res = eval('context.fn(' + args + ')') } delete context.fn return res }Copy the code

The last

Here is just a simple simulation implementation, which there are many details can be improved, such as the type of parameter judgment, writing optimization, etc