JavaScript函数调用和绑定

时间:2019-02-20 21:26:42

标签: javascript function binding method-invocation

我有以下部分代码:

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

var bind = function(func, thisValue) {
  return function() {
    return func.apply(thisValue, arguments);
  }
}

var boundHello = bind(person.hello, person);
boundHello("world") // "Brendan Eich says hello world"

在这里,代码将在控制台中打印出文本

  

Brendan Eich向世界问好

如果我接受绑定变量分配并将其更改为:

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

var bind = function(func, thisValue) {
  return func.apply(thisValue, arguments);
}

var boundHello = bind(person.hello, person);
boundHello("world") // "Brendan Eich says hello world"

那么结果就是

  

Brendan Eich说你好功能(事物){       console.log(this.name +“打个招呼” +东西); }

有人可以解释一下为什么会发生这种情况吗? bind 中的两个嵌套 return 函数到底是什么?

它们到底如何工作?

2 个答案:

答案 0 :(得分:3)

在第二个版本中,您在调用func时正在调用bind(),并返回函数调用的值。

它正在打印hello函数的源代码,因为arguments是类似数组的对象[person.hello, person],因此您实际上是在进行调用person.hello(person.hello, person),而这将thing设置为person.hello,然后将函数转换为字符串以进行串联,将返回其源代码。

要绑定一个函数,您必须返回一个闭包,以后可以调用它。在您的第一个版本中,这是通过返回匿名函数来完成的。

答案 1 :(得分:1)

我会尽力解释。在第一个示例中,您的bind定义是一个function,它有两个参数,理想情况下是 function 作为第一个参数(简称为 THE_FUNC )和一个对象作为第二个参数(简称为 THE_THIS_ARG ),将用作thisArgs该功能。

现在,此bind定义返回一个function,它不带任何参数(但可以带任何参数),当调用此函数时,它将返回评估值使用 THE_THIS_ARG 作为 THE_FUNC this的值并使用{{1}在 THE_FUNC 上调用apply }(称为 THE_ARGS )作为参数传递给 THE_FUNC

对于您的特定示例,设置将是以下示例:

THE_FUNC => arguments

THE_THIS_ARG => person.hello

THE_ARGS => person(类似数组的对象)

最后将["world"]引入类似(不完全)的内容:

boundHello("word")

也许,下一个带有一些调试的示例可以帮助您更好地理解我的解释:

person.hello.apply(person, ["world"]);

对于第二个示例,相同的解释也是有效的。但是在这种情况下,var person = { name: "Brendan Eich", hello: function(thing) { console.log(this.name + " says hello " + thing); } } var bind = function(func, thisValue) { console.log("func is: ", func); console.log("thisValue is: ", thisValue); return function() { console.log("Arguments are:", arguments); return func.apply(thisValue, arguments); } } var boundHello = bind(person.hello, person); boundHello("world") // "Brendan Eich says hello world"不会返回上一个示例中的函数,而是使用以下设置调用bind

THE_FUNC => apply

THE_THIS_ARG => person.hello

THE_ARGS => person(类似数组的对象)

因此,当您致电[person.hello, person]时,会被转为类似的内容:

bind(person.hello, person)

如您所见,person.hello.apply(person, [person.hello, person]); 将是person.hello方法接收到的thing参数,这就是在person.hello()处打印函数定义的原因论点。

thing