我有一个相当学术性的问题,不适用于我正在做的任何事情,我只是想知道答案!
假设我们在全局 namespace 中有一个简单的对象定义,如下所示:
TestObject = function(){};
它在原型(prototype)中添加了一个方法,可以实例化为新对象本身:
TestObject.prototype.AnotherObject = function() {};
实例化第一个对象:
var myObject = new TestObject();
现在我的问题是这样的:
如何
myObject.myProperty = new myObject.AnotherObject();
不同于
myObject.myProperty = new TestObject.prototype.AnotherObject();
还是完全一样?
我看到的区别是:我可以使用第二种方法在TestObject上下文中实例化对象,而无需知道实例化对象本身的名称,即
TestObject.prototype.createAnObject = function() {
this.anotherProperty = new TestObject.prototype.AnotherObject();
}
最后:
使用原型(prototype)方法实例化同名对象的含义是什么?为什么这会导致无限循环? (内部实际发生了什么。)
TestObject.prototype.AnotherObject = function () {
this.AnotherObject = new TestObject.prototype.AnotherObject();
};
myObject.AnotherObject();
但这不是...
TestObject.AnotherObject = function() {};
TestObject.prototype.createAnObject = function() {
this.AnotherObject = new TestObject.prototype.AnotherObject();
};
myObject.createAnObject();
...
我渴望了解这里的物体之间的关系!谢谢!
我问这些问题的原因是,我想做出这样的事情,使得对象之间存在1:1的关系:
ClientObject = function () {
this.objectname = "a client class";
}
ClientObject.prototype.loginUser = function(name) {
this.loggedin = true;
if (typeof this.User === 'undefined') {
this.User = new ClientObject.User(name);
}
}
ClientObject.User = function (name) {
this.username = name;
}
ClientObject.User.prototype.getProfile = function() {
return 'user profile';
}
var testClient = new ClientObject();
console.log('testClient.User = ' + (typeof testClient.User)); // should not exist
testClient.loginUser('Bob'); // should login 'bob'
console.log('testClient.User = ' + (typeof testClient.User)); // should exist now Bob is logged in
console.log(testClient.User.username); // should be bob
testClient.loginUser('Tom'); // should not do anything as User object already created
console.log(testClient.User.username); // bob still
console.log(testClient.User.getProfile()); // new functionality available
我只是不确定我是否在不经意间破坏了任何最佳实践或惯例。
最佳答案
完全没有区别。请记住,JavaScript中的对象具有原型(prototype)链。当您调用new myObject.AnotherObject();
时,引擎将首先在AnotherObject
本身上检查myObject
。找不到它,它将检查myObject
的原型(prototype),它将找到。第二版
myObject.myProperty = new TestObject.prototype.AnotherObject();
只需转到定义
AnotherObject
的位置即可。TestObject.prototype.AnotherObject = function () {
this.AnotherObject = new TestObject.prototype.AnotherObject();
}
myObject.AnotherObject();
只需遍历代码。当您说:
myObject.AnotherObject();
时,将调用AnotherObject
,并且this
设置为myObject
。第一行将尝试通过将其设置为的结果,在myObject
(即this
)上创建一个新属性。new TestObject.prototype.AnotherObject();
然后将重新输入非常相同的
AnotherObject
函数,但是这次将this
设置为一个新对象,该对象的原型(prototype)设置为TestObject.prototype.AnotherObject
的原型(prototype)。等等广告无限最后,
TestObject.prototype.createAnObject = function() {
this.AnotherObject = new TestObject.prototype.AnotherObject();
}
myObject.createAnObject();
据我所知,并且据我测试,不是是否会导致无限循环:FIDDLE
基本上,
createAnObject
将以this
设置为myObject
进入。在其中将在myObject上创建一个名为AnotherObject
的全新属性,该属性将设置为您先前设置的AnotherObject
函数的新调用。请注意,进行此调用后,
AnotherObject
函数仍将存在,但,将由刚创建的AnotherObject
属性由遮盖住。所以现在你永远无法说var f = new myObject.AnotherObject()
因为您现在在myObject上有一个
AnotherObject
属性属性,它将在对原型(prototype)进行任何检查之前找到并返回。好吧,我的意思是,您总是可以说
delete myObject.AnotherObject
并从对象中删除该属性,这将使您可以在原型(prototype)中找到AnotherObject
,但实际上,您应该避免这样的名称冲突。关于最后的代码
A)为什么不让
User
成为自己的函数?B)为什么不直接在ClientObject构造函数中设置
this.User = new ...()
?这样,您就不需要undefined
检查C)
ClientObject
应该定义为function ClientObject(){...`
您现在拥有的似乎正在创建一个隐式全局。