使用getter的结果复制对象

时间:2014-11-11 11:13:33

标签: javascript getter-setter

我有一个包含吸气剂的物体。

myObject {
    id: "MyId",
    get title () { return myRepository.title; }
}

myRepository.title = "MyTitle";

我想获得一个像这样的对象:

myResult = {
    id: "MyId", 
    title: "MyTitle"
}

我不想复制getter,所以:

myResult.title;                       // Returns "MyTitle"
myRepository.title = "Another title";
myResult.title;                       // Should still return "MyTitle"

我试过了:

  • $。extend():但它不会迭代getter。 http://bugs.jquery.com/ticket/6145
  • 按照建议的here迭代属性,但它不会迭代getter。
  • 当我使用angular时,使用Angular.forEach,如建议here。但我只得到属性而不是吸气剂。

有什么想法吗? THX!

更新 我使用Object.defineProperty将getter设置为:

 "title": { get: function () { return myRepository.title; }},

可以在文档中看到:

  

可枚举当且仅当此属性在此期间显示时才为true   枚举相应对象的属性。默认为   假的。

设置enumerable:true修复问题。

"title": { get: function () { return myRepository.title; }, enumerable: true },

2 个答案:

答案 0 :(得分:4)

$.extend完全符合您的要求。更新:您已经说过您想要不可枚举的属性,所以它< em>不会做你想做的事情;请参阅下面这个答案的第二部分,但我会留下第一部分给其他人。)这个错误并不是说结果对象不会拥有title属性,它表示生成的对象的title属性不会成为 getter ,这是你所说的你想要的完美。

使用正确的getter语法的示例:

&#13;
&#13;
// The myRepository object
var myRepository = { title: "MyTitle" };

// The object with a getter
var myObject = {
    id: "MyId",
    get title() { return myRepository.title; }
};

// The copy with a plain property
var copy = $.extend({}, myObject);

// View the copy (although actually, the result would look
// the same either way)
snippet.log(JSON.stringify(copy));

// Prove that the copy's `title` really is just a plain property:
snippet.log("Before: copy.title = " + copy.title);
copy.title = "foo";
snippet.log("After:  copy.title = " + copy.title);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
&#13;
&#13;

语法修正:

  • 添加了遗失var=;

  • 删除了重复的属性title

  • 更正了getter声明语法


如果您想要包含不可枚举的属性,则需要使用Object.getOwnPropertyNames,因为它们不会出现在for-in循环Object.keys中,或$.extend(无论他们是否&#34; getter&#34;或正常属性):

&#13;
&#13;
// The myRepository object
var myRepository = { title: "MyTitle" };

// The object with a getter
var myObject = {
    id: "MyId"
};
Object.defineProperty(myObject, "title", {
  enumerable: false, // it's the default, this is just for emphasis,
  get: function() {
    return myRepository.title;
  }
});

snippet.log("$.extend won't visit non-enumerable properties, so we only get id here:");
snippet.log(JSON.stringify($.extend({}, myObject)));

// Copy it
var copy = Object.getOwnPropertyNames(myObject).reduce(function(result, name) {
  result[name] = myObject[name];
  return result;
}, {});

// View the copy (although actually, the result would look
// the same either way)
snippet.log("Our copy operation with Object.getOwnPropertyNames does, though:");
snippet.log(JSON.stringify(copy));

// Prove that the copy's `title` really is just a plain property:
snippet.log("Before: copy.title = " + copy.title);
copy.title = "foo";
snippet.log("After:  copy.title = " + copy.title);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:3)

首先,修复你的语法,虽然它可能在你的实际代码中很好:

myObject = {
    id: "MyId",
    get title () { return myRepository.title; }
}

现在,回答。 :)

您可以使用for..in循环获取所有属性,然后按原样保存:

var newObj = {};
for (var i in myObject) {
    newObj[i] = myObject[i];
}

没有jQuery,Angular,还需要任何其他插件!