复制带有吸气剂结果的对象 [英] Copy object with results of getters
问题描述
我有一个包含吸气剂的对象.
myObject {
id: "MyId",
get title () { return myRepository.title; }
}
myRepository.title = "MyTitle";
我想获得一个像这样的对象
myResult = {
id: "MyId",
title: "MyTitle"
}
我不想复制吸气剂,所以:
myResult.title; // Returns "MyTitle"
myRepository.title = "Another title";
myResult.title; // Should still return "MyTitle"
我已经尝试:
- $.extend():但是它不会遍历getter. http://bugs.jquery.com/ticket/6145
- 根据建议的此处进行迭代的属性,但是不会迭代获取方法. li>
- 当我使用angular时,按照建议
可以在文档中阅读:
可枚举,当且仅当此属性在 对应对象的属性的枚举.默认为 错误.
可枚举的设置:确实解决了该问题.
"title": { get: function () { return myRepository.title; }, enumerable: true },
解决方案$.extend
完全满足您的要求.title
属性,表示生成的对象的title
属性不是 getter ,这对于您想要的内容来说是完美的. /p>使用正确的getter语法的示例:
// 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);
<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>
语法修复:
-
添加了缺少的
var
,=
和;
-
已删除重复属性
title
-
更正了getter声明语法
如果要包括不可枚举的属性,则需要使用
Object.getOwnPropertyNames
,因为它们不会出现在for-in
循环,Object.keys
或$.extend
中(无论它们是否重新获取"或常规属性):// 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);
<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>
I have an object that contains a getter.
myObject { id: "MyId", get title () { return myRepository.title; } } myRepository.title = "MyTitle";
I want to obtain an object like:
myResult = { id: "MyId", title: "MyTitle" }
I don't want to copy the getter, so:
myResult.title; // Returns "MyTitle" myRepository.title = "Another title"; myResult.title; // Should still return "MyTitle"
I've try:
- $.extend(): But it doesn't iterate over getters. http://bugs.jquery.com/ticket/6145
- Iterating properties as suggested here, but it doesn't iterate over getters.
- As I'm using angular, using Angular.forEach, as suggested here. But I only get properties and not getters.
Any idea? Thx!
Update I was setting the getter using Object.defineProperty as:
"title": { get: function () { return myRepository.title; }},
As can be read in the doc:
enumerable true if and only if this property shows up during enumeration of the properties on the corresponding object. Defaults to false.
Setting enumerable: true fix the problem.
"title": { get: function () { return myRepository.title; }, enumerable: true },
解决方案(Update: You've since said you want non-enumerable properties as well, so it doesn't do what you want; see the second part of this answer below, but I'll leave the first bit for others.) The bug isn't saying that the resulting object won't have a$.extend
does exactly what you want.title
property, it's saying that the resulting object'stitle
property won't be a getter, which is perfect for what you said you wanted.Example with correct getter syntax:
// 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);
<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>
Syntax fixes:
Added missing
var
,=
, and;
Removed duplicate property
title
Corrected the getter declaration syntax
If you want to include non-enumerable properties, you'll need to use
Object.getOwnPropertyNames
because they won't show up in afor-in
loop,Object.keys
, or$.extend
(whether or not they're "getter" or normal properties):// 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);
<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>
这篇关于复制带有吸气剂结果的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
-