问题描述
我有一个相当学术的问题,它并不特别适用于我正在做的任何事情,我真的很想知道答案!
I have a rather academic question that doesn't particularly apply to anything I'm doing, I just really want to know the answer!
假设我们在全局命名空间中有一个简单的对象定义:
Say we have a simple object definition in the global namespace as such:
TestObject = function(){};
它的原型中添加了一个方法,可以将其实例化为新对象本身:
It has a method added to it's prototype that can be instantiated into a new object itself:
TestObject.prototype.AnotherObject = function() {};
实例化第一个对象:
var myObject = new TestObject();
现在我的问题是:
怎么做
myObject.myProperty = new myObject.AnotherObject();
不同于
myObject.myProperty = new TestObject.prototype.AnotherObject();
或者它们完全一样?
我看到的不同之处在于:我可以使用第二种方法在 TestObject 上下文中实例化对象,而无需知道实例化对象本身的名称,即
The difference I see is this: I could use the second method to instantiate objects within the TestObject context without knowing the name of the instantiated object itself, i.e.
TestObject.prototype.createAnObject = function() {
this.anotherProperty = new TestObject.prototype.AnotherObject();
}
最后:
使用原型方法实例化同名对象有什么含义?为什么这会导致无限循环?(里面到底发生了什么..)
What are the implications of using a prototype method to instantiate an object of the same name? Why do this result in an infinite loop? (What actually happens inside..)
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();
...
我很想了解这里的对象之间的关系!谢谢!
I have a deep desire to understand the relationships between objects here! Thank you!
我问这些问题的原因是因为我想做这样的事情,其中对象之间存在 1:1 的关系:
The reason I ask these questions is because I want to make something like so where there is a 1:1 relationship between objects:
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
我只是不确定我是否在无意中违反了任何最佳做法或惯例.
I am just not sure if I'm breaking any best practises or conventions here unwittingly.
推荐答案
不同于
myObject.myProperty = new TestObject.prototype.AnotherObject();
myObject.myProperty = new TestObject.prototype.AnotherObject();
完全没有区别.请记住,JavaScript 中的对象有一个原型链.当您调用 new myObject.AnotherObject();
时,引擎将首先检查 myObject
本身上的 AnotherObject
.如果找不到它,它将检查 myObject
的原型,它会找到.第二个版本
There's no difference at all. Remember, objects in JavaScript have a prototype chain. When you call new myObject.AnotherObject();
the engine will first check for a AnotherObject
on myObject
itself. Failing to find it, it will check on myObject
's prototype, which it will find. The second version
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
)上创建一个新属性,方法是将其设置为
Just walk through the code. When you say: myObject.AnotherObject();
, AnotherObject
will be called, with this
set to myObject
. The first line of that will attempt to create a new property on myObject
(which is this
) by setting it to the result of
new TestObject.prototype.AnotherObject();
然后将重新输入完全相同的 AnotherObject
函数,但这次 this
设置为一个新对象,其原型设置为 TestObject.prototype.AnotherObject
的原型.等等无止境
which will then re-enter the very same AnotherObject
function, but this time with this
set to a new object whose prototype is set to TestObject.prototype.AnotherObject
's prototype. And so on ad infinitum
最后,
TestObject.prototype.createAnObject = function() {
this.AnotherObject = new TestObject.prototype.AnotherObject();
}
myObject.createAnObject();
是否不会导致无限循环,据我所知,据我所知:FIDDLE
Will not cause an infinite loop, so far as I can tell, and as far as I can test: FIDDLE
基本上,createAnObject
将在this
设置为myObject
的情况下进入.其中将在 myObject 上创建一个名为 AnotherObject
的全新属性,该属性将设置为您之前对 AnotherObject
函数 的新调用设置.
Basically, createAnObject
will enter with this
set to myObject
. Inside of which a brand new property called AnotherObject
will be created on myObject, which will be set to a new invocation of the AnotherObject
function you previously set up.
请注意,在进行此调用后,AnotherObject
函数 将仍然存在,但是,它将被您刚刚创建的 AnotherObject
属性遮蔽.所以现在你永远不能说
Note that after this call is made, the AnotherObject
function will still exist, but, it will be shadowed by the AnotherObject
property you just created. So now you'll never ever be able to say
var f = new myObject.AnotherObject()
因为您现在有一个 AnotherObject
property 就在 myObject 上,它将在检查原型上的任何内容之前被找到并返回.
Because you now have a AnotherObject
property sitting right on myObject, which will be found and returned before anything on the prototype is ever checked.
嗯,我的意思是,你总是可以说 delete myObject.AnotherObject
并从对象中删除该属性,然后你就可以看到 AnotherObject
在原型,但实际上,您应该避免这样的名称冲突.
Well, I mean, you could always say delete myObject.AnotherObject
and remove that property from the object, which would then open you up to the AnotherObject
being found on the prototype, but really, you should avoid name conflicts like this to begin with.
关于你的最后一点代码
A) 为什么不让 User
成为其自己的 功能?
B) 为什么不在 ClientObject 构造函数中设置 this.User = new ...()
?这样你就不需要 undefined
检查C) ClientObject
应该定义为
A) Why not make User
its own function?
B) Why not set up this.User = new ...()
right in the ClientObject constructor function? That way you wouldn't need the undefined
checkC) ClientObject
should be defined as
function ClientObject(){...`
您现在拥有的似乎正在创建一个隐式全局.
the you have it now seems to be creating an implicit global.
这篇关于Javascript:从已经实例化的对象与原型创建对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!