- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑下面的代码,
function Test(){
var a = 'prabhu';
Test.prototype.print = function (){ alert(a); a=10; }
}
我正在为测试创建对象实例,
var x = new Test();
var y = new Test();
现在正在访问 print
两者的方法在他们的原型(prototype)中可用,
x.print() //"prabhu" ok!!
x.print() //10 Double ok!!
但是
y.print() //10 what the?? It should be prabhu. Isn't it?
这是怎么回事?因为在创建 y
时例如,constructor
将被调用,它将覆盖 print
在其原型(prototype)中发挥作用。它将创建一个 closure
对于 a
具有值(value) "prabhu"
.因此,在通过 print()
访问它时它应该打印 "prabhu"
正确的?为什么这没有发生?对此行为的逐步解释将非常有帮助。
P.S:如果我们使用 this.a
,我知道代码的行为到处而不是a
和 var a
.所以请不要建议使用它。我正在努力弄清楚为什么会发生上述解释的行为。
最佳答案
永远不要将函数分配给 prototype
对象上的构造函数在构造函数中,它会设置此串扰。
原因是通过new Test
创建的对象有一个指向其原型(prototype)的实时链接,而不是它的副本。这意味着如果您修改原型(prototype)对象,下次该对象在其上查找某些内容(如 print
)时,它会看到新的对象。这是一件好事™,但它确实意味着您不应该从 Test
中分配给 Test.prototype
。
您看到的是您所看到的,因为当您执行 var y = new Test()
时,您正在更改现有 x
使用的原型(prototype),更改其 print
函数,以便它关闭来自第二次调用(创建 y
的调用)的 a
,而不是第一次调用。因此,如果您在执行此操作后调用 x.print()
,则更新的 a
是第二个,而不是第一个。
让我们跟随您的代码:
function Test(){
var a = 'prabhu';
Test.prototype.print = function (){ alert(a); a=10; }
}
var x = new Test();
此时,我们在内存中有这个(省略一些不相关的细节):
+---------------+ x-->| (object) | +---------------+ +----------+ | [[Prototype]] |---->| (object) | +---------------+ +----------+ +-----------------+ | print |-->| (function) | +----------+ +-----------------+ +---------------+ | env |-->| Environment 1 | | alert(a); a=10; | +---------------+ +-----------------+ | a: 'prabhu' | +---------------+
Now we do this:
var y = new Test();
现在我们有:
+-----------------+ +---------------+ +---------------+ | (function) | | Environment 1 |x-->| (object) | +-----------------+ +---------------+ +---------------+ | env |-->| a: 'prabhu' | | [[Prototype]] |--+ | alert(a); a=10; | +---------------+ +---------------+ | +-----------------+ | | +----------+ +-----------------+ +---------------+ +->| (object) | | (function) | | Environment 2 | | +----------+ +-----------------+ +---------------+ | | print |-->| env |-->| a: 'prabhu' | | +----------+ | alert(a); a=10; | +---------------+ | +-----------------+ +---------------+ |y-->| (object) | | +---------------+ | | [[Prototype]] |--+ +---------------+
Note that the old print
function is no longer connected to the object x
refers to in any way; it's been replaced with the new one, which refers to the new environment created by calling Test
a second time.The old function and the environment it used to close over are both eligible for garbage collection now.
Then:
x.print() //"prabhu" ok!!
给我们(我暂时留下了垃圾;也许它被收集了,也许没有,没关系):
+-----------------+ +---------------+ +---------------+ | (function) | | Environment 1 |x-->| (object) | +-----------------+ +---------------+ +---------------+ | env |-->| a: 'prabhu' | | [[Prototype]] |--+ | alert(a); a=10; | +---------------+ +---------------+ | +-----------------+ | | +----------+ +-----------------+ +---------------+ +->| (object) | | (function) | | Environment 2 | | +----------+ +-----------------+ +---------------+ | | print |-->| env |-->| a: 10 | | +----------+ | alert(a); a=10; | +---------------+ | +-----------------+ +---------------+ |y-->| (object) | | +---------------+ | | [[Prototype]] |--+ +---------------+
Note that the call changed the a
from the second call to Test
(the one that created y
), not the first one (the garbage).
Then:
x.print() //10 Double ok!!
不改变任何东西。
最后:
y.print() //10 what the?? It should be prabhu. Isn't it?
出于完全相同的原因显示 10 x.print()
显示 10:print
函数正在使用 a
来自 second 调用 Test
,而不是第一个。
关于javascript - 构造函数中闭包的神秘行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35794914/
我正在尝试更新我的 jtable(更改值并按 Enter 键),但出现错误。由于大小原因,错误未完整。我认为其余部分只是 c3p0 池连接工具生成的不相关信息。 假设 起初,我认为这可能是 c3p0
每当我有两个水平并排的元素并指定了右和/或左填充和/或边距时,元素之间通常会在我指定的上方和上方有空格。我希望有人能告诉我如何消除该空间(没有像负边距这样的笨拙东西)。 请注意:我并不是在寻找替代的多
String[] parts = msg.split(" +\n?"); String room = parts[0]; System.out.println(msg); Sy
我知道“一定有什么东西被改变了”,但我的代码似乎在一夜之间无缘无故地崩溃了。 我的服务器目录结构是这样的: / /scripts /audit /other_things 我在“scripts”文件夹
我正在尝试了解 GCM 的工作原理。为此,我复制/粘贴 http://developer.android.com/ 的代码在“实现 GCM 客户端”部分中提出。 从服务器发送消息是可行的,但是当我的客
在生成随机整数时,我发现了一些有趣的事情(至少对我而言),我无法向自己解释,所以我想我会把它贴在这里。 我的需求很简单:我要生成随机积分 (Int32) ID 并旨在最大程度地减少冲突。生成时间不是问
在这里https://stackoverflow.com/a/19915925/4673197我了解到我可以通过设置 IFS 将字符串拆分为数组。 在这里https://stackoverflow.c
我现在正在为我的 CS 测试学习,并尝试编写代码,以明文形式给出整个 IMDB 数据库,找到电影中共同点最多的 Actor 。我已经差不多完成了,只是不断遇到一个奇怪的 KeyError。这是我的代码
在 Android 平台上开发了几个月之后,我仍然有一个悬而未决的问题。很久以前,我注意到我有一个 Activity 不符合应用程序主题的其余部分。这意味着默认情况下,Activity 的字体颜色是白
本周,我注意到我的团队 Azure 门户上有一个持续的网络作业。 团队中没有人表示他们已经部署了它,或者熟悉它。我找到了这个博客: https://azure.microsoft.com/en-ca/
所以我正在制作一个小型闲置游戏,我的部分努力是格式化所有数字,以便它们之间有逗号(出于美观目的)。我成功地让我的货币 Energy 带有这些逗号,但我很难添加其他变量。我用了num.toLocaleS
我遇到了一个我以前从未见过的奇怪问题,我认为它一定是一些我在代码中没有看到的简单问题。 我有一个项目,其中定义了 2 个 Windows 服务。一个我称为 DataSyncService,另一个称为
我有这个jsfiddle一次有效。 function toggle_off(itemID){ alert(itemID+'->'+document.getElementById(itemID).g
更新:已解决,我是白痴,谢谢大家! Okay little bit weird.. I just created a layout file for list items, I can see it
问题:这段代码究竟在做什么? 另外:“w”的使用方式是否是某种现有算法?我试图弄清楚函数的意图,或者至少描述它产生的数字种类。 上下文:我正在查看 Martin O'Leary 的“Fantasy M
你能帮帮我吗?我正在将自己传递给它自己的纯虚函数。 n->dataCallback(handler, n, hangup); 其中 n 是我的类指针,dataCallback 是它自己的(纯)虚函数(
我知道这里有数百万篇关于这个异常(exception)的帖子,但我不明白这里的这个。我有一个极端简单的示例管道服务: [ServiceContract] public interface ISRARi
此代码有效,但它如何不实际调用任何列出的方法。它有效,但它的工作原理和原因似乎几乎是神奇的。我实际上从未调用过 Equals、GetHashCode 或 Compare,但代码有效。我也从不在实现两个
警告: Element 'TextStyle' from SDK library 'ui.dart' is implicitly hidden by 'text_style.dart'. 代码摘录:
我有一个似乎无法解开的谜。我有这个非常简单的单元测试,它使用了一个非常简单的自定义属性。该属性仅添加到甚至未实例化的 1 个类。我计算属性被构建的次数。由于类 MyDummyClass 上的属性,我希
我是一名优秀的程序员,十分优秀!