Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

The best way to really understand something is to implement it yourself. Today, we will introduce how to understand and use call and apply to call functions by implementing call and apply ourselves.

const tut = {
  title:"machine learning"
};

function getTitle(){
  console.log(`title: The ${this.title}`)
}

getTitle.call(tut);
Copy the code

Define an object tut and then define a function getTitle, which directly executes getTitle(). This refers to the window. Calling the function getTitle with call binds this to the tut object. So you can use the object property title in the output.

To understand call, let’s create a call

The best way to understand how the Call method is used and what happens behind the wheel is to implement a call method yourself.

const tut = {
    title:"machine learning"
}

function description(){
    console.log(`title: The ${this.title}`)}Function.prototype.newCall = function(obj){
    console.log(this);
}

description.newCall(tut);
Copy the code
index.js:10 ƒ description(){
    console.log(`title: The ${this.title}`)}Copy the code

Since tut is not yet bound to this, this is now the description function itself.

Function.prototype.newCall = function(obj){
    obj.tmp = this;
    obj.tmp();
    // console.log(this);
    delete obj.tmp;
}
Copy the code
function description(subTitle,summay,type){
    console.log(`title: The ${this.title}`);
    console.log(subTitle,summay,type);//undefined undefined undefined}... description.newCall(tut,'machine learning'.'summary'.'video');
Copy the code
const tut = {
    title:"machine learning"
}

function description(subTitle,summay,type){
    console.log(`title: The ${this.title}`)
    console.log(subTitle,summay,type);
}

Function.prototype.newCall = function(obj){
    var obj = obj || window
    obj.tmp = this;
    var newArguments = [];
    for (let i = 1; i < arguments.length; i++) {
        newArguments.push('arguments[' + i +'] ');
    }
    
    console.log(newArguments)
    eval('obj.tmp(' + newArguments + ') ');
    // console.log(this);
    delete obj.tmp;
}

description.newCall(null.'machine learning'.'summary'.'video');
Copy the code
const tut = {
    title:"machine learning"
}

function description(subTitle,summay,type){
    // console.log(`title: ${this.title}`)
    // console.log(subTitle,summay,type);
    return {
        title:this.title,
        subTitle:subTitle,
        summay:summay,
        type:type
    }

}

Function.prototype.newCall = function(obj){
    var obj = obj || window
    obj.tmp = this;
    var newArguments = [];
    for (let i = 1; i < arguments.length; i++) {
        newArguments.push('arguments[' + i +'] ');
    }
    
    console.log(newArguments)
    const result = eval('obj.tmp(' + newArguments + ') ');
    // console.log(this);
    delete obj.tmp;
    return result;
}

const res = description.newCall(tut,'machine learning'.'summary'.'video');
console.log(res)//{title: 'machine learning', subTitle: 'machine learning', summay: 'summary', type: 'video'}
Copy the code

The realization of the aplly

The apply method is similar to call. The first argument is the object that calls the method. The second argument is an array of parameters.

const tut = {
    title:"machine learning"
}

function description(subTitle,summay,type){
    console.log(`title: The ${this.title}`)
    console.log(subTitle,summay,type);
    // return {
    // title:this.title,
    // subTitle:subTitle,
    // summay:summay,
    // type:type
    // }

}

Function.prototype.newApply = function(obj,arr){
    var obj = obj || window
    obj.tmp = this;
    if(! arr){ obj.tmp() }else{

        var newArguments = [];
        for (let i = 0; i < arr.length; i++) {
            newArguments.push('arr[' + i +'] ');
        }
        
        const result = eval('obj.tmp(' + newArguments + ') ');
    }
    delete obj.tmp;
}

description.newApply(tut,['machine learning'.'summary'.'video']);
Copy the code