使用 bind 强制创建原型函数的上下文
Using bind to force the context of a prototype function
我正在研究一些JavaScript代码,这些代码将用于为我们的企业级软件构建"类"(特别是视图模型)的构造函数。我正在做的一件事是建立一个代码强制设计模式,其中实现者将显式定义他们希望由类实例公开哪些函数,代码将它们添加到构造函数的prototype
,而不是类的每个实例的属性。当然,这样做的好处是每种类型只有一个实例,而不是每个实例都有一个实例。
这是我大多数示例的代码笔。
问题是,在某些条件下,我正在处理绑定损失问题。例如,使用此构造函数:
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
,因此调用sadGreet("Denny")
时this.firstName
不存在。
因此,我想出的一个解决方案是用调用该原型的属性覆盖原型,并将其包装在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
复制为属性,还是我对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 的每个实例现在都有一个唯一且新的"greet"函数对象("bind"函数创建一个新的函数对象)。
看看你的代码,甚至在Bar.prototype上拥有"greet"功能实际上变得有点复杂。相反,这也适用于:
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");
您可以通过简单地尝试以下命令来测试"greet"函数是否与每个实例的"greet"函数不同:
console.log( greet === happyGreet );
- 将函数的上下文应用于javascript变量
- 是否可以在不更改上下文的情况下调用函数.apply
- 调用$.each()函数时上下文发生变化
- 如何向onClick事件处理程序传递一个接受参数的函数,并且仍然将该函数绑定到组件's”;这个“;上下文
- 访问函数对象的上下文属性|如何
- 构造函数函数中的自执行函数的OO上下文/范围
- node.js中的箭头函数上下文
- Javascript Ninja:数组中的当前元素作为函数上下文
- underscore.js debounce函数中的内部函数上下文
- 离开函数上下文后,Javascript数组内容将消失
- Javascript函数上下文
- & # 39; functionInBackboneView& # 39;在Jquery中不是一个函数上下文
- 如何构造原型,使函数上下文不指向“原型”对象?
- 将变量传递给函数上下文
- 点击释放函数上下文
- 在JavaScript中更改函数上下文(用于访问局部变量)
- Javascript:使用函数上下文与作为参数传递的好处是什么?
- 嵌套函数中的函数上下文(“this”)
- 事件类型字段的打字稿事件处理程序函数 - 上下文不正确
- JavaScript函数上下文错误