Javascript:从已经实例化的对象创建对象与原型

时间:2013-06-03 02:08:50

标签: javascript object prototype theory

我有一个相当学术性的问题并不特别适用于我正在做的任何事情,我只是想知道答案!

假设我们在全局命名空间中有一个简单的对象定义:

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

我不确定我是否在不知不觉中违反了任何最佳做法或惯例。

1 个答案:

答案 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。第一行将尝试通过将其设置为

的结果在myObjectthis)上创建新属性
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(){...` 

你现在似乎正在创建一个隐含的全局。