制作自己对象的副本而不是引用(更新帖子,不同的 Q) [英] Making a copy of an own object instead of a reference (updated post, different Q)

查看:34
本文介绍了制作自己对象的副本而不是引用(更新帖子,不同的 Q)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍然掌握它的窍门,这对你们中的很多人来说可能是逻辑.但是我已经更新了这篇文章,说明我是如何工作的,可能有人会通过搜索来到这里.

I am still getting the hang of it, and its probally logic for a lot of you. But I've updated the post with how I got it working, might some one come here by search.

声明:

var test=Element({"id" : 1, "name" : "wrapper"}).
      append(Element({"id" : 2, "name" : "elm A"}),
             Element({"id" : 3, "name" : "elm b"})
      );

alert(test.getInfo("name"));
alert(test.aArguments["children"][1].getInfo("name"));

'类':

var Element = function ($aPassArguments) {
    aArguments: {
            "id" : false,
            "name" : false,
            "type" : false,
            "title" : false, 
            "style" : false,
            "action" : [],
            "parent" : false,
            "children" : []
        };
    for (var prop in this.aArguments)
            if (prop in $aPassArguments) 
                this.aArguments[prop] = $aPassArguments[prop];
    return {
        append: function () {
            $argList = arguments;
            for ($i = 0; $i < $argList.length; $i++)
                if (typeof $argList[$i]=="string")
                    this.setChild(this.importDB($argList[$i],true));
                else
                    this.setChild($argList[$i]);
        },
         setChild: function($oChild) {
            this.aArguments["children"][this.aArguments["children"].length]=$oChild; 
        }
    };
};

...........................................

.............................................................

我不知道 JavaScript 中的新对象实例是引用而不是副本.现在我想要一份我自己的对象元素的副本.显然(感谢@blurd)我希望它成为工厂混合动力车:http://javascript.info/tutorial/factory-constructor-pattern

I wasnt aware a new object instance in javascript is a reference instead of a copy. Now I want to have a copy of my own object Element. Apperantly (thanks @blurd) I want it to be a factory hybrid: http://javascript.info/tutorial/factory-constructor-pattern

感谢@blurd 的帮助和我定义了一些问题,我想出了如下解决方案:

Thanks to the help of @blurd and me defining some problems, I came up with a sollution like the following:

其中我最终获得了 Element 对象的副本而不是引用.下面的好答案并没有完全解决我的问题.但这是由于我对问题的澄清和理解不力

In which I finaly got copies of my Element object instead of references. The good answers below didnt completly solve my problem. But this is due to my poor clarification and understanding of the problems

var Element = function (initialConfig) {

    return {
        aArguments: {
            "id" : false,
            "name" : false,
            "type" : false,
            "title" : false, 
            "style" : false,
            "action" : [],
            "parent" : false,
            "children" : [],
        },


        create:function ($aPassArguments) {
            for (var prop in this.aArguments)
                if (prop in $aPassArguments) 
                    this.aArguments[prop] = $aPassArguments[prop];
        },
        append: function () {
            $argList = arguments;
            for ($i = 0; $i < $argList.length; $i++)
                if (typeof $argList[$i]=="string")
                    this.setChild(this.importDB($argList[$i],true));
                else
                    this.setChild($argList[$i]);
        },
         setChild: function($oChild) {
            this.aArguments["children"][this.aArguments["children"].length]=$oChild; 
        }
    };
};

用法

var test=Element();
test.create({"id" : 1, "name" : "wrapper"});
var test2=Element();
test2.create({"id" : 2, "name" : "elm A"});
test3.create({"id" : 3, "name" : "elm B"});
test.append(test2,test3);

alert(test.aArguments["name"]);
alert(test.aArguments["children"][0].aArguments["name"]);

现在我对用法很不满意,我希望它是一行并再次使用构造函数.这可能是可能的,而且……经过更多的自学后,我可能会解决它.但现在我已经完成了:P 刚刚用这个更新了我的帖子.当我再次得到它并有更好的声明时,我会再次更新它.也许有人可能会分享一种方法(更好的方法)来做到这一点.最终有这样的事情:

Now I am very unhappy about the usage,I would like it be one line and use a constructor again. And this is probally possible, and... after some more selfschooling I will probally solve it. But for now I am done with it :P just updated my post with this. When I get to it again and have a beter declaration I will update it again. And perhaps someone might share a way (beter way) to do this. To eventually have something like this:

var test=new Element({"id" : 3, "name" : "wrapper"})
           .append( new Element{"id" : 3, "name" : "elm A"}), 
                    new Element({"id" : 3, "name" : "elm B"}) 
                  );

...........................................................................................

.............................................................................................

我在这里胡思乱想,我搜索的有关 javascript 和对象的所有内容都告诉我相同,这还不够,因为我无法弄清楚为什么以下代码无法正常工作:

I am pulling my hair outs here, everything I search about javascript and objects tells me the same, which is not enough, because I cant figure out why the following code isnt working propaly:

例如我正在制作一个这样的对象:

For example I am making an object like this:

var Element = {
    aArguments: {                                                       //set Default arguments
        "id" : false,
        "name" : false,
        "type" : false,
        "title" : false, 
        "style" : false,
        "action" : [],
        "parent" : false,
        "children" : {},
    },
    create:function ($aPassArguments) {
        for (var prop in this.aArguments)
            if (prop in $aPassArguments) 
                this.aArguments[prop] = $aPassArguments[prop];
        return this;
    },
    append: function () {
        $argList = arguments;
        for ($i = 0; $i < $argList.length-1; $i++)
            if (typeof $argList[$i]=="string")
                this.setChild(this.importDB($argList[$i],true));
            else
                this.setChild($argList[$i]);
        return this;
    },
    setChild: function($oChild) {
        this.aArguments["children"][this.aArguments["children"].length-1]=$oChild; 
    },
    getInfo: function($sKey) {
        return this.aArguments[$sKey];
    }
};

在调用 .create() 时将 $aPassArgumentsthis.Arguments 合并(我不知道是否可以使用 '__constructor').替换 aArguments.

Which merges $aPassArguments with this.Arguments on calling of .create() (I cant figureif its possible to use a '__constructor'). To replace given proparties in aArguments.

并使用 .append 将传递的对象添加到 aArguments["childeren"].

And add passed object(s) with .append to aArguments["childeren"].

但是当我这样调用对象时:

But when I call the object like this:

$set=(Element.create({"id": 1, "name" : "wrapper"})).
     append(Element.create({"id" : 3, "name" : "elm A"}));
alert($set.getInfo("name"));

它会提醒我Elm A"而不是wrapper".

It will alert me "Elm A" and not "wrapper".

我认为这是因为我不是在创建 Element 的新对象,而是在处理同一个对象.现在对我来说逻辑解决方案和开始是写:

I assume that this is because I am not creating a new object of Element, but are working on the same object. Now to me the logical solution and start would be to write:

$set=(new Element.create({"id": 1, "name" : "wrapper"})).
     append(new Element.create({"id" : 3, "name" : "elm A"}));
alert($set.getInfo("name"));

但我收到错误:TypeError: (intermediate value).append 不是函数

but I get the error: TypeError: (intermediate value).append is not a function

为什么我的代码没有按照我的预期工作?是否有可能,如果有,如何向对象添加构造函数?所以我可以跳过调用 .create 并使用:

Why isnt my code not working as supposed by me? And is it possible and if so how do I add a constructor to an object? So I could skip calling .create and use:

 $set=new Element({"id": 1, "name" : "wrapper"}).
     append(new Element({"id" : 3, "name" : "elm A"}));

推荐答案

您说得对,您应该使用 new 运算符.除此之外,看起来您正在尝试将其设为某种类型的 factory 混合.我建议如下.

You are right, you should be using the new operator. Aside from that, it looks like you're trying to make this some type of factory hybrid. I suggest the following.

包括一个您可以在创建对象时使用的可选配置.

Include an optional configuration that you can use when creating the object.

var Element = function (initialConfig) {
    if (initialConfig) {
        this.create(initialConfig);
    }
};

添加到原型

您所有共享的 Element 成员都应该是 原型.

Element.prototype = {
    aArguments: {
        "id" : false,
        "name" : false,
        "type" : false,
        "title" : false, 
        "style" : false,
        "action" : [],
        "parent" : false,
        "children" : {},
    },
    create:function ($aPassArguments) {
        for (var prop in this.aArguments)
            if (prop in $aPassArguments) 
                this.aArguments[prop] = $aPassArguments[prop];
        return this;
    },
    append: function () {
        $argList = arguments;
        for ($i = 0; $i < $argList.length-1; $i++)
            if (typeof $argList[$i]=="string")
                this.setChild(this.importDB($argList[$i],true));
            else
                this.setChild($argList[$i]);
        return this;
    },
    setChild: function($oChild) {
        this.aArguments["children"][this.aArguments["children"].length-1]=$oChild; 
    },
    getInfo: function($sKey) {
        return this.aArguments[$sKey];
    }
};

示例

您的示例现在应该可以按预期工作.请注意,您不能调用 new Element.create(),因为这会将 Element.create 视为构造函数.相反,将您的初始值传递给构造函数.

Examples

Your examples should now work as you expected. Notice that you can't call new Element.create() as that would treat Element.create as a constructor. Instead, pass your initial values into the constructor.

$set = new Element({"id": 1, "name" : "wrapper"}).
     append(new Element({"id" : 3, "name" : "elm A"}));

alert($set.getInfo("name"));

小心

您没有在循环中检查自己的属性,省略了 {},而且我发现了至少一个隐含的全局属性.如果你不小心,JavaScript 会咬你.考虑使用 JSLintJSHint 帮助您发现这些问题.

Be Careful

You're not checking for own properties in your loops, omitting {}, and I spotted at least one implied global. JavaScript will bite you if you're not careful. Consider using JSLint or JSHint to help you spot these problems.

这篇关于制作自己对象的副本而不是引用(更新帖子,不同的 Q)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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