gpt4 book ai didi

javascript - 使用绑定(bind)强制原型(prototype)函数的上下文

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:16:46 24 4
gpt4 key购买 nike

我正在编写一些 JavaScript 代码,这些代码将用于为我们的企业级软件构建“类”(特别是 View 模型)的构造函数。我正在做的一件事是建立一个代码强制设计模式,实现者将明确定义他们希望类的实例公开哪些功能,代码会将它们添加到 prototype 中。构造函数的属性,而不是类的每个实例的属性。这当然有一个优势,即每个类型的每个函数只有一个实例,而不是每个实例都有一个实例。

Here's a CodePen of most of my examples.

问题是在某些情况下,我正在处理 binding loss问题。例如,使用此构造函数:

  function Foo(myName) {
this.firstName = myName;
}

Foo.prototype.greet = function(yourName) {
alert("Hello, " + yourName + ". I am " + this.firstName + ".");
}

...这会起作用:

var sam = new Foo("Sam");
// Alerts "Hello, Denny. I am Sam."
sam.greet("Denny");

...但这不会:

var sad = new Foo("Sad");
// This changes the context of greet. :(
var sadGreet = sad.greet;
// Alerts "Hello, Denny. I am undefined."
sadGreet("Denny");

这是因为当我们做 var sadGreet = sad.greet我们正在更改 greet 的上下文功能window , 所以 this.firstName调用时不存在 sadGreet("Denny") .

因此,我想到的一个解决方案是用调用该原型(prototype)的属性覆盖原型(prototype),将其包装在 Function.prototype.bind() 中。 :

function Bar(myName) {
this.firstName = myName;
// Here's where the magic happens.
this.greet = Bar.prototype.greet.bind(this);
}

Bar.prototype.greet = function(yourName) {
alert("Hello, " + yourName + ". I am " + this.firstName + ".");
}

var happy = new Bar("Happy");
// Since each instance of Bar overwrites the context for greet, this will work. :)
var happyGreet = happy.greet;
// Alerts "Hello, Denny. I am Happy."
happyGreet("Denny");

我的问题是:我假设 Bar效率不如Foo ,但这是否完全取消了声明 greet 的任何好处?作为 prototype方法?在幕后它只是复制greet作为属性(property),无论如何,或者是我调用bind只需为 Bar.prototype.greet 添加一个“包装器” ?换句话说,这实际上与上面对 Bar 的定义完全相同吗?

function Bar(myName) {
this.firstName = myName;
// Here's where the magic happens.
this.greet = function(yourName) {
alert("Hello, " + yourName + ". I am " + this.firstName + ".");
}
}

如果您不仅能回答问题,还能告诉我如何测试它,可加分!

最佳答案

Bar 肯定比 Foo 效率低,但不是在时间复杂度方面。相反,它在内存消耗方面的效率较低,因为 Bar 的每个实例现在都有一个唯一的和新的“问候”函数对象(“绑定(bind)”函数创建一个新的函数对象)。

看看你的代码,它实际上变得有点复杂,甚至在 Bar.prototype 上有“问候”功能。相反,这也适用:

function Bar(myName) {
this.firstName = myName;
this.greet = greet.bind(this);
}

var greet = function(yourName) {
alert("Hello, " + yourName + ". I am " + this.firstName + ".");
};

var happy = new Bar("Happy");
var happyGreet = happy.greet;
happyGreet("Denny");

您可以通过简单地尝试以下操作来测试“问候”功能是否与每个实例的“问候”功能相同:

console.log( greet === happyGreet );

关于javascript - 使用绑定(bind)强制原型(prototype)函数的上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27712385/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com