【发布时间】:2018-10-10 14:30:05
【问题描述】:
我在将两个对象与属性 getter/setter 合并时遇到了一些问题,这些属性会降级为值。如何预防?我必须手动克隆它吗?
下面是我的 pb 的人为示例:
function Factory1() {
const p = {};
return {
get prop1 () { return p.prop; },
set prop1 (value) { p.prop = value; }
};
}
function Factory2() {
const p = {};
return {
get prop2 () { return p.prop; },
set prop2 (value) { p.prop = value; }
}
}
const obj1 = Factory1();
const obj2 = Factory2();
const obj3a = {...Factory1(), ...Factory2()};
const obj3b = Object.assign(Factory1(), Factory2());
console.log('obj1.prop1 =>', Object.getOwnPropertyDescriptor(obj1, 'prop1'));
console.log('obj2.prop2 =>', Object.getOwnPropertyDescriptor(obj2, 'prop2'));
console.log('spread prop1 =>', Object.getOwnPropertyDescriptor(obj3a, 'prop1'));
console.log('spread prop2 =>', Object.getOwnPropertyDescriptor(obj3a, 'prop2'));
console.log('assign prop1 =>', Object.getOwnPropertyDescriptor(obj3b, 'prop1'));
console.log('assign prop2 =>', Object.getOwnPropertyDescriptor(obj3b, 'prop2'));
2018 年 10 月 11 日更新
一个更简单的例子:
function Factory1() {
return {
get prop1 () { return 42; }
};
}
const obj1 = Factory1();
const obj2 = Object.assign({}, Factory1())
console.log('obj1.prop1 =>', Object.getOwnPropertyDescriptor(obj1, 'prop1'));
// result
// obj1.prop1 => { get: [Function],
// set: undefined,
// enumerable: true,
// configurable: true }
console.log('obj2.prop1 =>', Object.getOwnPropertyDescriptor(obj2, 'prop1'));
// result
// obj2.prop1 => { value: 42,
// writable: true,
// enumerable: true,
// configurable: true }
一个更真实的例子
根据要求,我将尝试说明我所面临的代码类型。当然,这是在多个模块中调度的代码提取的串联。
import axios from 'axios';
function createAxios (options = {}) {
const axiosClient = axios.create(options);
axiosClient.defaults.withCredentials = false;
axiosClient.defaults.headers.common['Accept'] = 'text/html';
return {axiosClient};
}
function WithQuery ({axiosClient}) {
// This is a sample server that supports CORS.
var sampleUrl = 'http://html5rocks-cors.s3-website-us-east-1.amazonaws.com/index.html';
return {
query (url) {
return axiosClient.get(url || sampleUrl);
}
};
}
function WithLastModified (context) {
let lastModified;
context.axiosClient.interceptors.response.use(function (response) {
const {headers} = response;
console.log('header last-modified:', headers['last-modified']);
lastModified = headers['last-modified'];
return response;
});
return {
getLastModified () {
return lastModified;
},
get lastModified () {
return lastModified;
}
}
}
function build (options) {
const httpClient = createAxios(options);
return Object.assign({},
httpClient,
{search: WithQuery(httpClient)},
WithLastModified(httpClient));
}
const api = build();
api.search.query().then(() => {
console.log('get lastModified:', api.lastModified); // not working, always undefined
console.log('getLastModified:', api.getLastModified()); // work
});
这种类型的工厂方法用于注入依赖项并通过伪混合向最终对象添加功能。
【问题讨论】:
-
您的用例到底是什么?如果您不想共享私有
p对象,那么是的,您将不得不手动克隆方法。 -
可能的解决方法here
标签: javascript