1

任何人都可以解释 JavaScript 在调用方法以选择运行哪个函数时所经历的过程吗?我可以找到的大多数在线资源都解释了如何使用 JavaScript 对象实现特定行为,但没有解释方法调度在 JavaScript 中的工作原理。

4

1 回答 1

8

“方法分派”实际上只是属性查找,因为 JavaScript 中的“方法”只是通过对象属性使用的函数。(更多关于我的博客:神话方法

当你写:

obj.prop

JavaScript 引擎查看obj对象以查看它是否具有名称为 的属性"prop"。如果是,则使用该属性的值。如果没有,引擎会查找原型对象obj以查看是否具有具有该名称的属性。如果是这样,它使用它的值。如果不是,它会查看对象的原型。冲洗,重复,直到它用完原型对象。

在某些允许方法重载的语言中,没有任何类型的“方法签名”匹配JavaScript 没有方法重载。给定名称的对象只能附加一个属性。

让我们看一个例子:

function Thing() {
}
Thing.prototype.test = function() {
    return "Thing#test";
};

var t = new Thing();
t.own = function() {
    return "My own";
};

现在让我们玩t

console.log(t.own());  // Logs "My own"

对于表达式t.own,引擎t会查看它是否有一个名为 的属性"own"。确实如此,因此使用了该属性(函数)的值。()after 它调用该函数,该函数返回,"My own"我们就完成了。

console.log(t.test()); // Logs "Thing#test"

对于表达式t.test,引擎t会查看它是否有一个名为 的属性"test"。它没有,所以引擎会查看t的原型。t的原型是Thing.prototype,它是在表达式期间分配给它的new ThingThing.prototype有一个"test"属性,所以使用那个(函数)的值。然后()after 它调用该函数,该函数返回 string "Thing#test"

console.log(t.toString()); // Logs "[object Object]"

引擎查看t,没有找到"toString"属性,所以它查看t' 原型,但没有找到"toString"属性,所以它查看t' 原型的原型(即Object.prototype)。那确实有一个"toString"属性,其值是一个函数。然后()调用该函数,该函数返回"[object Object]".

最后,为了完整性:

console.log(t.foo());      // Throws an error

"foo"引擎在tt的原型或t' 原型的原型上找不到。现在它没有原型了,所以表达式的t.foo结果是undefined. 然后我们尝试通过调用它(),我们不能这样做,因为undefined它不是一个函数。

于 2013-08-23T12:08:23.727 回答