我有一个相当学术性的问题并不特别适用于我正在做的任何事情,我只是想知道答案!
假设我们在全局命名空间中有一个简单的对象定义:
TestObject = function(){};
它有一个方法添加到它的原型中,可以将其实例化为一个新对象本身:
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();
}
最后:
使用原型方法实例化同名对象有什么含义?为什么这会导致无限循环? (里面发生了什么......)
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
我不确定我是否在不知不觉中违反了任何最佳做法或惯例。
答案 0 :(得分:4)
myObject.myProperty = new myObject.AnotherObject();
与
不同myObject.myProperty = new TestObject.prototype.AnotherObject();
完全没有区别。请记住,JavaScript中的对象具有原型链。当您致电new myObject.AnotherObject();
时,引擎会首先检查AnotherObject
本身myObject
。如果找不到它,它将检查它将找到的myObject
原型。第二个版本
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
设置为一个新对象,其原型设置为TestObject.prototype.AnotherObject
的原型。等等 ad infinitum
最后,
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()
因为您现在有一个AnotherObject
属性坐在myObject上,在找到原型上的任何内容之前,会找到并返回该属性。
嗯,我的意思是,你总是可以说delete myObject.AnotherObject
并从对象中删除该属性,这会打开你到原型上找到的AnotherObject
,但实际上,你应该避免像这样的名字冲突开始。
关于你的最后一段代码
A)为什么不让User
使用拥有功能?
B)为什么不在ClientObject构造函数中设置this.User = new ...()
?这样你就不需要undefined
检查了
C)ClientObject
应定义为
function ClientObject(){...`
你现在似乎正在创建一个隐含的全局。