2015-12-17 2 views
3

В следующей ситуации я нахожу, что lodash, кажется, не копировать поглотитель из исходного объекта:Есть ли способ сделать lodash copy свойство getters и seters?

const _ = require("lodash"); 

let sourceObject = { }; 
Object.defineProperty(sourceObject, "abc", { 
    get:() => 123 
}); 

let cloneObject = _.cloneDeep(sourceObject); 

console.log(sourceObject.abc); // 123 
console.log(cloneObject.abc); // undefined 

Есть ли способ для достижения выше с lodash модуля?

ответ

3

Только в том случае, если определено свойство enumerable. Это приведет к тому, что он будет обнаружен с помощью Object.keys(), что в конечном итоге означает, что lodash получает список имен свойств. Это настраивается, если вы определяете свойство с опцией {enumerable: true}, но по умолчанию оно равно false, поэтому _.cloneDeep не подбирает вашу недвижимость.

Для получения более подробной информации см. the MDN docs for Object.defineProperty.

+0

Потрясающие спасибо за супер быстрый ответ !! отлично работает: D –

+1

Кажется, что lodash deepClone действительно найдет геттер, если он перечислим, но не сделает копию геттера в новом объекте. Вместо этого он будет получать доступ к значению, используя getter и clone, которые будут использовать значение raw. Кажется, что клоун объектного объекта отсутствует в определении геттера ??? – Moonwalker

+2

Да, получение значений прямолинейно. Создание «истинного клона» для некоторого определения этого [сложно выразить мягко] (http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object) –

-1

Так жаль, что поздно к партии, но я думал, что это заслуживает правильное решение для записи, так как я просто решил это для себя:

const hasGetter = (obj, prop) => !!Object.getOwnPropertyDescriptor(obj, prop)['get'] 
const copyProperty = (obj1, obj2, propName) => Object.defineProperty(obj2, propName, Object.getOwnPropertyDescriptor(obj1, propName)) 
const copyObject = (obj) => Object.keys(obj).reduce((a, x) => copyProperty(obj, a, x), {}) 

// DEMO 
let from = { 
    one: 1, 
    two: "two" 
} 

// define a getter 
Object.defineProperty(from, "seconds", { 
    get: function() { 
     return (new Date()).getSeconds() 
    }, 
    enumerable: true 
}) 

const to = copyObject(from) 

// prove it worked 
let count = 0 
let id = setInterval(() => { 
    console.log(hasGetter(to, "seconds"), to.seconds) 
    count++ 
    if (count > 5) clearInterval(id) 
}, 1000) 
Смежные вопросы