Javascript:从已经实例化的对象与原型创建对象 [英] Javascript: creation of object from an already instantiated object versus the prototype

查看:50
本文介绍了Javascript:从已经实例化的对象与原型创建对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 myObject.AnotherObject();

myObject.myProperty = new myObject.AnotherObject();

不同于

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 check C) ClientObject should be defined as

function ClientObject(){...` 

您现在拥有的似乎正在创建一个隐式全局.

the you have it now seems to be creating an implicit global.

这篇关于Javascript:从已经实例化的对象与原型创建对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆