我已经知道apply和call是类似的函数,它们设置this(函数的上下文)。

区别在于我们发送参数的方式(manual vs array)

问题:

但是什么时候应该使用bind()方法呢?

var obj = {
  x: 81,
  getX: function() {
    return this.x;
  }
};

alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));

jsbin


当前回答

最简单形式的答案

调用函数并允许您逐个传入参数 一个。 Apply调用函数并允许传入参数 作为一个数组。 Bind返回一个新函数,允许传入 此数组和任意数量的参数。


应用、调用和绑定示例

Call

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}

say.call(person1, 'Hello'); // Hello Jon Kuperman
say.call(person2, 'Hello'); // Hello Kelly King

应用

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say(greeting) {
    console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}

say.apply(person1, ['Hello']); // Hello Jon Kuperman
say.apply(person2, ['Hello']); // Hello Kelly King

Bind

var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say() {
    console.log('Hello ' + this.firstName + ' ' + this.lastName);
}

var sayHelloJon = say.bind(person1);
var sayHelloKelly = say.bind(person2);

sayHelloJon(); // Hello Jon Kuperman
sayHelloKelly(); // Hello Kelly King

什么时候使用

Call和apply是可以互换的。只需要决定发送一个数组还是一个以逗号分隔的参数列表更容易。

我总是记住哪个是哪个,记住Call是为逗号(分隔列表)和Apply是为数组。

Bind有点不同。它返回一个新函数。Call和Apply立即执行当前函数。

Bind对很多事情都很有用。我们可以像上面的例子一样使用它来curry函数。我们可以使用一个简单的hello函数,并将其转换为helloJon或helloKelly。我们也可以将它用于像onClick这样的事件,我们不知道它们什么时候会被触发,但我们知道我们想让它们拥有什么上下文。

参考:codeplanet.io

其他回答

JavaScript调用()

const person = {
    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.call(anotherPerson,1,2)

JavaScript应用()

    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.apply(anotherPerson,[1,2])

**call和apply函数是不同的,调用单独的参数,但应用数组 如:(1、2、3) **

JavaScript绑定()

    name: "Lokamn",
    dob: 12,
    anotherPerson: {
        name: "Pappu",
        dob: 12,
        print2: function () {
            console.log(this)
        }
    }
}

var bindFunction = person.anotherPerson.print2.bind(person)
 bindFunction()

它们都将其附加到函数(或对象)中,区别在于函数调用(见下文)。

Call将此附加到函数中并立即执行函数:

var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
person.hello.call({ name: "Jim Smith" }, "world"); // output: "Jim Smith says hello world"

Bind将它附加到函数中,需要像这样单独调用:

var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
var helloFunc = person.hello.bind({ name: "Jim Smith" });
helloFunc("world");  // output: Jim Smith says hello world"

或者像这样:

...    
var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
helloFunc();  // output: Jim Smith says hello world"

Apply类似于call,只是它接受一个类似数组的对象,而不是一次列出一个参数:

function personContainer() {
  var person = {  
     name: "James Smith",
     hello: function() {
       console.log(this.name + " says hello " + arguments[1]);
     }
  }
  person.hello.apply(person, arguments);
}
personContainer("world", "mars"); // output: "James Smith says hello mars", note: arguments[0] = "world" , arguments[1] = "mars"                                     

JavaScript中call()、apply()和bind()方法的第一个区别是它们的执行时间! Call()和apply()是相似的立即执行,而bind()创建了一个新函数,我们必须在任何稍后的时间显式调用!

另一个区别是,在传递参数时,call()允许我们用逗号分隔一个一个地传递,apply()允许我们作为参数数组传递,而bind()允许我们两者都做!

我已附上下面的示例代码!

const person = {
    fullName : function (randomMessage) {
        return `Hello, ${this.firstName} ${this.lastName} ${randomMessage}`;
    }
}

const personOne = {
    firstName : "John",
    lastName : "Doe"
}

const personTwo = {
    firstName : "Jack",
    lastName : "Adhikari"
}

let fullNameBind = person.fullName.bind(personOne, "--Binding");
let fullNameCall = person.fullName.call({firstName : "Sarah", lastName: "Holmes"}, "--Calling");
let fullNameApply = person.fullName.apply(personTwo, ["--Applying"]);

console.log(fullNameBind());
console.log(fullNameCall);
console.log(fullNameApply);

语法

呼叫(thisArg, arg1, arg2, .) (thisArg专心,argsArray) bind(thisArg[, arg1] [, arg2])

Here

thisArg是对象 argArray是一个数组对象 Arg1, arg2, arg3,…是额外的参数

function printBye(message1, message2){ console.log(message1 + " " + this.name + " "+ message2); } var par01 = { name:"John" }; var msgArray = ["Bye", "Never come again..."]; printBye.call(par01, "Bye", "Never come again..."); //Bye John Never come again... printBye.call(par01, msgArray); //Bye,Never come again... John undefined //so call() doesn't work with array and better with comma seperated parameters //printBye.apply(par01, "Bye", "Never come again...");//Error printBye.apply(par01, msgArray); //Bye John Never come again... var func1 = printBye.bind(par01, "Bye", "Never come again..."); func1();//Bye John Never come again... var func2 = printBye.bind(par01, msgArray); func2();//Bye,Never come again... John undefined //so bind() doesn't work with array and better with comma seperated parameters

调用apply和bind。以及它们的不同之处。

让我们学习如何使用日常术语。

你有三辆汽车,你的摩托车,你的汽车和你的喷气式飞机,它们以相同的机制(方法)开始。 我们使用push_button_engineStart方法创建了一个对象汽车。

var your_scooter, your_car, your_jet;
var automobile = {
        push_button_engineStart: function (runtime){
        console.log(this.name + "'s" + ' engine_started, buckle up for the ride for ' + runtime + " minutes");
    }
}

让我们理解什么时候使用call和apply。让我们假设你是一名工程师,你有你的摩托车,你的汽车和你的喷气式飞机,这些都没有push_button_engine_start,你希望使用第三方push_button_engineStart。

如果运行以下代码行,它们将给出一个错误。为什么?

//your_scooter.push_button_engineStart();
//your_car.push_button_engineStart();
//your_jet.push_button_engineStart();


automobile.push_button_engineStart.apply(your_scooter,[20]);
automobile.push_button_engineStart.call(your_jet,10);
automobile.push_button_engineStart.call(your_car,40);

上面的例子成功地给了your_scooter, your_car, your_jet一个automobile对象的特征。

让我们再深入一点 在这里,我们将拆分上面的代码行。 汽车。push_button_engineStart帮助我们获取正在使用的方法。

此外,我们使用点表示法使用apply或call。 automobile.push_button_engineStart.apply ()

现在应用和调用accept两个参数。

上下文 参数

这里我们在最后一行代码中设置了context。

automobile.push_button_engineStart.apply (your_scooter [20])

call和apply的区别在于apply接受数组形式的形参,而call只能接受以逗号分隔的参数列表。

什么是JS绑定函数?

绑定函数基本上就是绑定某个东西的上下文,然后将其存储到一个变量中,以便在稍后阶段执行。

让我们把前面的例子做得更好。之前我们使用了一个属于automobile对象的方法,并使用它来装备你的car、你的jet和你的scooter。现在让我们想象一下,我们想要分别给出一个单独的push_button_engineStart,在我们希望的执行的任何后续阶段分别启动我们的汽车。

var scooty_engineStart = automobile.push_button_engineStart.bind(your_scooter);
var car_engineStart = automobile.push_button_engineStart.bind(your_car);
var jet_engineStart = automobile.push_button_engineStart.bind(your_jet);


setTimeout(scooty_engineStart,5000,30);
setTimeout(car_engineStart,10000,40);
setTimeout(jet_engineStart,15000,5);

还不满意?

让我们像泪滴一样说清楚。是时候做实验了。我们将返回到调用和应用函数应用程序,并尝试将函数的值存储为引用。

下面的实验失败了,因为call和apply是立即调用的,因此,我们从来没有达到在变量中存储引用的阶段,这是bind函数的亮点

var test_function = automobile.push_button_engineStart.apply(your_scooter);