我已经知道apply
和call
是设置this
(函数的上下文)的类似函数。
区别在于我们发送参数的方式(手动与数组)
问题:
但什么时候应该使用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));
答案 0 :(得分:740)
如果希望稍后使用特定上下文调用该函数,请使用.bind()
,这在事件中很有用。如果要立即调用该函数,请使用.call()
或.apply()
,然后修改上下文。
调用/应用立即调用该函数,而bind
返回一个函数,该函数在稍后执行时将具有用于调用原始函数的正确上下文集。这样,您就可以在异步回调和事件中维护上下文。
我做了很多:
function MyObject(element) {
this.elm = element;
element.addEventListener('click', this.onClick.bind(this), false);
};
MyObject.prototype.onClick = function(e) {
var t=this; //do something with [t]...
//without bind the context of this function wouldn't be a MyObject
//instance as you would normally expect.
};
我在Node.js中广泛使用它来处理我想传递成员方法的异步回调,但仍希望上下文成为启动异步操作的实例。
一个简单,天真的bind实现就像:
Function.prototype.bind = function(ctx) {
var fn = this;
return function() {
fn.apply(ctx, arguments);
};
};
还有更多内容(比如传递其他args),但您可以阅读更多相关内容并查看真实的实现on the MDN。
希望这有帮助。
答案 1 :(得分:413)
他们都将 这个 附加到函数(或对象)中,区别在于函数调用(见下文)。
调用将 此 附加到函数中并立即执行该函数:
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"
应用类似于调用,只是它需要一个类似数组的对象,而不是一次列出一个参数:
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"
答案 2 :(得分:148)
以简单形式回答
拨打强>
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
<强>绑定强>
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是for逗号(分隔列表)而Apply是for Array。
绑定有点不同。它返回一个新函数。 Call和Apply立即执行当前功能。
Bind很适合很多事情。我们可以使用它来调整上面例子中的函数。我们可以使用一个简单的hello函数并将其转换为helloJon或helloKelly。我们也可以将它用于像onClick这样的事件,我们不知道什么时候它们会被解雇,但我们知道我们希望它们有什么背景。
答案 3 :(得分:52)
它允许设置this
的值,与函数的调用方式无关。这在使用回调时非常有用:
function sayHello(){
alert(this.message);
}
var obj = {
message : "hello"
};
setTimeout(sayHello.bind(obj), 1000);
使用call
获得相同的结果将如下所示:
function sayHello(){
alert(this.message);
}
var obj = {
message : "hello"
};
setTimeout(function(){sayHello.call(obj)}, 1000);
答案 4 :(得分:42)
假设我们有multiplication
功能
function multiplication(a,b){
console.log(a*b);
}
让我们使用bind
var multiby2 = multiplication.bind(this,2);
现在multiby2(b)等于乘法(2,b);
multiby2(3); //6
multiby2(4); //8
如果我传递bind
中的两个参数怎么办?var getSixAlways = multiplication.bind(this,3,2);
现在getSixAlways()等于乘法(3,2);
getSixAlways();//6
甚至传递参数返回6;
getSixAlways(12); //6
var magicMultiplication = multiplication.bind(this);
这会创建一个新的乘法函数并将其赋值给magicMultiplication。
哦不,我们将乘法功能隐藏在magicMultiplication中。
主叫
magicMultiplication
会返回空白function b()
执行时它工作正常
magicMultiplication(6,5); //30
打电话和申请怎么样?
magicMultiplication.call(this,3,2); //6
magicMultiplication.apply(this,[5,2]); //10
简单来说,bind
创建函数,call
和apply
执行函数,而apply
期望数组中的参数
答案 5 :(得分:28)
Function.prototype.call()
和Function.prototype.apply()
都会调用具有给定this
值的函数,并返回该函数的返回值。
Function.prototype.bind()
创建一个具有给定this
值的新函数,并返回该函数而不执行它。
所以,让我们看一个看起来像这样的函数:
var logProp = function(prop) {
console.log(this[prop]);
};
现在,让我们看一个如下所示的对象:
var Obj = {
x : 5,
y : 10
};
我们可以将我们的函数绑定到我们的对象:
Obj.log = logProp.bind(Obj);
现在,我们可以在代码中的任何位置运行Obj.log
:
Obj.log('x'); // Output : 5
Obj.log('y'); // Output : 10
真正有趣的地方是,当你不仅为this
绑定一个值,而且为其参数prop
绑定时:
Obj.logX = logProp.bind(Obj, 'x');
Obj.logY = logProp.bind(Obj, 'y');
我们现在可以这样做:
Obj.logX(); // Output : 5
Obj.logY(); // Output : 10
答案 6 :(得分:26)
前一段时间,我在函数对象,函数调用,DECLARE @MyTableVar TABLE (sysendtime datetime2);
DELETE
FROM dbo.someTable
OUTPUT DELETED.sysendtime INTO @MyTableVar
WHERE
colA = 'something';
SELECT sysendtime FROM @MyTableVar;
和call/apply
之间创建了这种比较:
bind
允许您设置.bind
值 now ,同时允许您将来执行函数 ,因为它会返回新的功能对象。
答案 7 :(得分:19)
bind :它使用提供的值和上下文绑定函数,但它不执行该函数。要执行功能,您需要调用该函数。
调用:它使用提供的上下文和参数执行函数。
apply :它使用提供的上下文和执行函数 参数为数组。
答案 8 :(得分:17)
以下是一个good article来说明bind()
,apply()
和call()
之间的区别,总结如下。
bind()
允许我们在调用函数或方法时轻松设置将哪个特定对象绑定到 this 。
// This data variable is a global variable
var data = [
{name:"Samantha", age:12},
{name:"Alexis", age:14}
]
var user = {
// local data variable
data :[
{name:"T. Woods", age:37},
{name:"P. Mickelson", age:43}
],
showData:function (event) {
var randomNum = ((Math.random () * 2 | 0) + 1) - 1; // random number between 0 and 1
console.log (this.data[randomNum].name + " " + this.data[randomNum].age);
}
}
// Assign the showData method of the user object to a variable
var showDataVar = user.showData;
showDataVar (); // Samantha 12 (from the global data array, not from the local data array)
/*
This happens because showDataVar () is executed as a global function and use of this inside
showDataVar () is bound to the global scope, which is the window object in browsers.
*/
// Bind the showData method to the user object
var showDataVar = user.showData.bind (user);
// Now the we get the value from the user object because the this keyword is bound to the user object
showDataVar (); // P. Mickelson 43
bind()
允许我们借用方法
// Here we have a cars object that does not have a method to print its data to the console
var cars = {
data:[
{name:"Honda Accord", age:14},
{name:"Tesla Model S", age:2}
]
}
// We can borrow the showData () method from the user object we defined in the last example.
// Here we bind the user.showData method to the cars object we just created.
cars.showData = user.showData.bind (cars);
cars.showData (); // Honda Accord 14
此示例的一个问题是我们在showData
对象上添加了一个新方法cars
我们可能不想只是借用一个方法,因为cars对象可能已经有一个属性或方法名showData
。
我们不想意外覆盖它。我们将在下面对Apply
和Call
的讨论中看到,
最好使用Apply
或Call
方法借用方法。
bind()
允许我们讨论一个函数
Function Currying,也称为部分功能应用,是使用a 函数(接受一个或多个参数)返回一个已经设置了一些参数的新函数。
function greet (gender, age, name) {
// if a male, use Mr., else use Ms.
var salutation = gender === "male" ? "Mr. " : "Ms. ";
if (age > 25) {
return "Hello, " + salutation + name + ".";
}else {
return "Hey, " + name + ".";
}
}
我们可以使用bind()
来理解这个greet
函数
// So we are passing null because we are not using the "this" keyword in our greet function.
var greetAnAdultMale = greet.bind (null, "male", 45);
greetAnAdultMale ("John Hartlove"); // "Hello, Mr. John Hartlove."
var greetAYoungster = greet.bind (null, "", 16);
greetAYoungster ("Alex"); // "Hey, Alex."
greetAYoungster ("Emma Waterloo"); // "Hey, Emma Waterloo."
apply()
或call()
设置此值
apply
,call
和bind
方法都用于在调用方法时设置此值,并且它们稍微执行
允许在我们的JavaScript代码中使用直接控制和多功能性的不同方法。
设置此值时,apply
和call
方法几乎相同,只是您将函数参数作为数组传递给apply ()
,而您必须单独列出参数以将它们传递给call ()
方法。
以下是使用call
或apply
在回调函数中设置 this 的一个示例。
// Define an object with some properties and a method
// We will later pass the method as a callback function to another function
var clientData = {
id: 094545,
fullName: "Not Set",
// setUserName is a method on the clientData object
setUserName: function (firstName, lastName) {
// this refers to the fullName property in this object
this.fullName = firstName + " " + lastName;
}
};
function getUserInput (firstName, lastName, callback, callbackObj) {
// The use of the Apply method below will set the "this" value to callbackObj
callback.apply (callbackObj, [firstName, lastName]);
}
// The clientData object will be used by the Apply method to set the "this" value
getUserInput ("Barack", "Obama", clientData.setUserName, clientData);
// the fullName property on the clientData was correctly set
console.log (clientData.fullName); // Barack Obama
借助apply
或call
借用数组方法
让我们创建一个array-like
对象并借用一些数组方法来操作类似数组的对象。
// An array-like object: note the non-negative integers used as keys
var anArrayLikeObj = {0:"Martin", 1:78, 2:67, 3:["Letta", "Marieta", "Pauline"], length:4 };
// Make a quick copy and save the results in a real array:
// First parameter sets the "this" value
var newArray = Array.prototype.slice.call (anArrayLikeObj, 0);
console.log (newArray); // ["Martin", 78, 67, Array[3]]
// Search for "Martin" in the array-like object
console.log (Array.prototype.indexOf.call (anArrayLikeObj, "Martin") === -1 ? false : true); // true
另一种常见情况是将arguments
转换为数组,如下所示
// We do not define the function with any parameters, yet we can get all the arguments passed to it
function doSomething () {
var args = Array.prototype.slice.call (arguments);
console.log (args);
}
doSomething ("Water", "Salt", "Glue"); // ["Water", "Salt", "Glue"]
借用其他方法
var gameController = {
scores :[20, 34, 55, 46, 77],
avgScore:null,
players :[
{name:"Tommy", playerID:987, age:23},
{name:"Pau", playerID:87, age:33}
]
}
var appController = {
scores :[900, 845, 809, 950],
avgScore:null,
avg :function () {
var sumOfScores = this.scores.reduce (function (prev, cur, index, array) {
return prev + cur;
});
this.avgScore = sumOfScores / this.scores.length;
}
}
// Note that we are using the apply () method, so the 2nd argument has to be an array
appController.avg.apply (gameController);
console.log (gameController.avgScore); // 46.4
// appController.avgScore is still null; it was not updated, only gameController.avgScore was updated
console.log (appController.avgScore); // null
使用apply()
执行变量arity 功能
Math.max
是变量函数的一个例子,
// We can pass any number of arguments to the Math.max () method
console.log (Math.max (23, 11, 34, 56)); // 56
但是,如果我们有一组数字传递给Math.max
怎么办?我们不能这样做:
var allNumbers = [23, 11, 34, 56];
// We cannot pass an array of numbers to the the Math.max method like this
console.log (Math.max (allNumbers)); // NaN
这是apply ()
方法帮助我们执行可变参数函数的地方。而不是上述,我们必须使用apply (
)传递数字数组:
var allNumbers = [23, 11, 34, 56];
// Using the apply () method, we can pass the array of numbers:
console.log (Math.max.apply (null, allNumbers)); // 56
答案 9 :(得分:11)
所有这些方法背后的主要概念是功能挖掘。
函数借用使我们可以在不同对象上使用一个对象的方法,而不必复制该方法并将其维护在两个单独的位置。这是通过使用来完成的。 call()。 apply()或。 bind(),所有这些都可以在我们要借用的方法上显式设置
下面是所有这些方法的示例
let name = {
firstname : "Arham",
lastname : "Chowdhury",
}
printFullName = function(hometown,company){
console.log(this.firstname + " " + this.lastname +", " + hometown + ", " + company)
}
致电
第一个参数,例如call方法中的name始终是引用 (此)变量,后者将是函数变量
printFullName.call(name,"Mumbai","Taufa"); //Arham Chowdhury, Mumbai, Taufa
应用
apply方法与call方法相同 唯一的区别是,函数参数在数组列表中传递
printFullName.apply(name, ["Mumbai","Taufa"]); //Arham Chowdhury, Mumbai, Taufa
绑定
bind方法与call相同,区别在于,bind返回一个函数,该函数稍后可以通过调用它来使用(不立即调用它)
let printMyNAme = printFullName.bind(name,"Mumbai","Taufa");
printMyNAme(); //Arham Chowdhury, Mumbai, Taufa
printMyNAme()是调用该函数的函数
下面是jsfiddle的链接
答案 10 :(得分:8)
呼叫/应用立即执行功能:
func.call(context, arguments);
func.apply(context, [argument1,argument2,..]);
bind 不立即执行函数,但返回包装的 apply 函数(以供稍后执行):
function bind(func, context) {
return function() {
return func.apply(context, arguments);
};
}
答案 11 :(得分:6)
Call,Apply和Bind之间的基本区别是:
如果要使执行上下文出现在图片的后面,将使用绑定。
例如:
var car = {
registrationNumber: "007",
brand: "Mercedes",
displayDetails: function(ownerName){
console.log(ownerName + ' this is your car ' + '' + this.registrationNumber + " " + this.brand);
}
}
car.displayDetails('Nishant'); // **Nishant this is your car 007 Mercedes**
假设我要在其他变量中使用此方法
var car1 = car.displayDetails('Nishant');
car1(); // undefined
要在其他变量中使用car的引用,则应使用
var car1 = car.displayDetails.bind(car, 'Nishant');
car1(); // Nishant this is your car 007 Mercedes
让我们谈谈绑定函数的更广泛使用
var func = function() {
console.log(this)
}.bind(1);
func();
// Number: 1
为什么?因为现在func是与数字1绑定的,如果在这种情况下不使用bind的话,它将指向全局对象。
var func = function() {
console.log(this)
}.bind({});
func();
// Object
您想同时执行该语句时使用调用,应用。
var Name = {
work: "SSE",
age: "25"
}
function displayDetails(ownerName) {
console.log(ownerName + ", this is your name: " + 'age' + this.age + " " + 'work' + this.work);
}
displayDetails.call(Name, 'Nishant')
// Nishant, this is your name: age25 workSSE
In apply we pass the array
displayDetails.call(Name, ['Nishant'])
// Nishant, this is your name: age25 workSSE
答案 12 :(得分:5)
答案 13 :(得分:4)
调用apply并绑定。以及它们如何不同。
让我们学习电话并使用任何日常术语进行申请。
你有三辆汽车your_scooter , your_car and your_jet
,它们以相同的机制(方法)开头。
我们使用方法automobile
创建了一个对象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");
}
}
让我们了解什么时候打电话和申请使用。假设您是一名工程师,并且your_scooter
,your_car
和your_jet
没有附带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
帮助我们了解所使用的方法。
此外,我们使用点符号进行应用或调用。
automobile.push_button_engineStart.apply()
现在应用并调用accept两个参数。
所以这里我们在最后一行代码中设置上下文。
automobile.push_button_engineStart.apply(your_scooter,[20])
call和apply之间的区别只是apply接受数组形式的参数,而call只是可以接受以逗号分隔的参数列表。
什么是JS绑定功能?
绑定函数基本上绑定某事物的上下文,然后将其存储到变量中以便在稍后阶段执行。
让我们的前一个例子更好。之前我们使用了属于汽车对象的方法并用它来装备your_car, your_jet and your_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);
仍不满意?
让我们说清楚泪滴。是时候试验了。我们将返回调用并应用函数应用程序并尝试存储函数的值作为参考。
下面的实验失败,因为调用和apply立即被调用,因此,我们永远不会进入在变量中存储引用的阶段,这是bind函数窃取show的地方
var test_function = automobile.push_button_engineStart.apply(your_scooter);
答案 14 :(得分:4)
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)
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函数是差异调用,采用单独的参数,但应用take数组 像:[1,2,3] **
name: "Lokamn",
dob: 12,
anotherPerson: {
name: "Pappu",
dob: 12,
print2: function () {
console.log(this)
}
}
}
var bindFunction = person.anotherPerson.print2.bind(person)
bindFunction()
答案 15 :(得分:3)
调用:调用会调用该函数,并允许您一个个传递参数
应用:应用会调用该函数,并允许您将参数作为数组传递
绑定: Bind返回一个新函数,使您可以传入this数组和任意数量的参数。
var person1 = {firstName: 'Raju', lastName: 'king'};
var person2 = {firstName: 'chandu', lastName: 'shekar'};
function greet(greeting) {
console.log(greeting + ' ' + this.firstName + ' ' + this.lastName);
}
function greet2(greeting) {
console.log( 'Hello ' + this.firstName + ' ' + this.lastName);
}
greet.call(person1, 'Hello'); // Hello Raju king
greet.call(person2, 'Hello'); // Hello chandu shekar
greet.apply(person1, ['Hello']); // Hello Raju king
greet.apply(person2, ['Hello']); // Hello chandu shekar
var greetRaju = greet2.bind(person1);
var greetChandu = greet2.bind(person2);
greetRaju(); // Hello Raju king
greetChandu(); // Hello chandu shekar
答案 16 :(得分:2)
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
答案 17 :(得分:1)
想象一下,绑定不可用。 您可以按照以下方式轻松构建它:
var someFunction=...
var objToBind=....
var bindHelper = function (someFunction, objToBind) {
return function() {
someFunction.apply( objToBind, arguments );
};
}
bindHelper(arguments);
答案 18 :(得分:0)
it('Environnement et logo sont affichés', () => {
browser.refresh();
expect(dashboard.getTextByCss('.tag-css')).toEqual('value');
expect(dashboard.getElementByCss('img[src*=\'image-name.png\']').isPresent()).toBe(true);
});
答案 19 :(得分:0)
call():-在这里,我们分别传递函数参数,而不是以数组格式传递
var obj = {name: "Raushan"};
var greeting = function(a,b,c) {
return "Welcome "+ this.name + " to "+ a + " " + b + " in " + c;
};
console.log(greeting.call(obj, "USA", "INDIA", "ASIA"));
apply():-在这里,我们以数组格式传递函数参数
var obj = {name: "Raushan"};
var cal = function(a,b,c) {
return this.name +" you got " + a+b+c;
};
var arr =[1,2,3]; // array format for function arguments
console.log(cal.apply(obj, arr));
bind():-
var obj = {name: "Raushan"};
var cal = function(a,b,c) {
return this.name +" you got " + a+b+c;
};
var calc = cal.bind(obj);
console.log(calc(2,3,4));
答案 20 :(得分:0)
将bind用于将来对该函数的调用。 apply
和call
都调用该函数。
bind()
还允许将其他参数附加到args数组。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
答案 21 :(得分:-1)
我认为它们的相同之处是:它们都可以改变函数的这个值。它们的区别在于:bind函数将返回一个新函数作为结果; call和apply方法会立即执行该函数,但apply可以接受一个数组作为params,它会解析分离的数组。而且,bind函数可以是Currying。
答案 22 :(得分:-3)
bind函数
var demo = {
getValue : function(){
console.log('demo object get value function')
}
setValue : function(){
setTimeout(this.getValue.bind(this),1000)
}
}
在上面的例子中,如果我们调用demo.setValue()函数并直接传递this.getValue函数,那么它不会直接调用demo.setValue函数,因为这在setTimeout中引用了window对象所以我们需要将demo对象上下文传递给this.getValue函数使用bind。它意味着我们只使用demo对象的上下文传递函数而不是实际调用函数。
希望你明白。了解更多信息,请参阅 javascript bind function know in detail