制作一个自己的对象,而不是引用的副本(更新后,不同的Q)(Making a copy of an o

2019-09-30 07:28发布

我仍然得到它的窍门,它probally逻辑很多你。 但我已经更新了帖子与我是如何得到它的工作,可能会有人来这里被搜索。

宣布:

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中一个新的对象实例的引用而不是复制。 现在,我想有自己的对象元素的副本。 Apperantly(感谢@blurd)我想这是一个工厂的混合: http://javascript.info/tutorial/factory-constructor-pattern

由于@blurd的帮助和我确定了一些问题,我想出了类似以下的sollution:

(但我不与我使用声明happying下文)

在我finaly得到了我的元素对象,而不是引用的副本。 下面didnt好答案完全地解决我的问题。 但是,这是由于我的问题,差的澄清和理解

诸如此类的解决方案

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"]);

现在,我对使用很不高兴,我想它是一个线,然后再次使用一个构造函数。 这是probally可能的,而且......经过一番更多selfschooling我将probally解决这个问题。 但现在,我用它做:P刚刚更新了我的职务与此有关。 当我一遍,有一个尤为明显的声明,我会更新一次。 也许有人会分享方式(尤为明显方式​​)来做到这一点。 最终是这样的:

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

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

旧文章

在这里,我拉我的头发出局,一切,我搜索关于JavaScript和对象告诉我同样的,这是不够的,因为我无法弄清楚,为什么下面的代码心不是propaly工作:

比如我提出这样一个目标:

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];
    }
};

其中合并$上调用.createthis.Arguments aPassArguments()(我不能figureif它可以使用“__constructor”)。 要aArguments更换给出proparties。

并用.append添加传递的对象(一个或多个),以aArguments [ “childeren”]。

但是,当我调用该对象是这样的:

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

它会提醒我“榆树A”,而不是“包装”。

我认为这是因为我没有创造元素的新对象,但在同一对象上都在工作。 现在,我的逻辑解决方案,开始是写:

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

但我得到的错误:类型错误:(中间值).append不是一个函数

为什么心不是我的代码不工作由我像预想的那样? 而且是有可能,如果让我怎么构造函数添加到对象? 所以,我可以跳过调用.create及用途:

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

Answer 1:

你说得对,你应该使用new运营商。 除此之外,它看起来像你试图做一些这方面的类型的工厂混合。 我建议以下。

使用构造函数

包括一个可选配置创建对象时,您可以使用。

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作为构造。 相反,通过你的初始值到构造。

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

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

小心

你不是在你的循环检查自己的属性,忽略{}我发现至少一个暗示全球。 如果你不小心的JavaScript会咬你。 考虑使用的JSLint或JSHint来帮助你发现这个问题。



Answer 2:

您创建功能不会产生任何对象,而是改变对地方的Element. aArguments Element. aArguments对象。 任何奇怪的事情可能会随之而来。
总之,只要去一个清洁,简单的原型继承方案,不使用$,记得要经常声明你的增值经销商,并让事情变得简单:

function Element(initialValues) {
    this.id = this.prototype.id++;
    this.name = null;
    this.type = null;
    this.title = null;
    this.style = null;
    this.action = [];
    this.parent = null;
    this.children = [];
    for (var prop in initialValues)
        if (this[prop] != undefined) this[prop] = initialValues[prop];
}

Element.prototype = {
    append: function () {
        for (var i = 0; i < arguments.length - 1; i++) {
            var thisElement = arguments[i];
            if (typeof thisElement == "string") this.setChild(this.importDB(thisElement, true));
            else this.setChild(thisElement);
        }
        return this;
    },
    setChild: function (child) {
        this.children.push(child);
        return this;
    },
    getInfo: function (key) {
        return this[Key];
    },
    id: 0
};


文章来源: Making a copy of an own object instead of a reference (updated post, different Q)