问题描述
我想做这样的事情:
let DOM = {
slide1: {
button: ".btn",Box: "#Box"
}
}
然后我写的时候:
console.log(DOM.slide1.Box);
经过一些研究,我尝试使用ES6代理对象,但是问题并没有通过以下方式解决:
const dom_names = {
slide1: {
button: ".btn",Box: "#Box"
}
}
const DOM_handler = {
get: (target,property,receiver)=>{
if(property == "slide1") return "#slide1";
return Reflect.get(...arguments);
}
}
const DOM = new Proxy(dom_names,DOM_handler);
此实现之后,我认识到我需要编写以下内容以获得所需的结果:
console.log(`${DOM.slide1} ${DOM.create.Box}) // #slide1 #Box
如您所见,这是一种非常糟糕的方法,我当时正在考虑使用我的解决方案(使用代理),但是问题是:我需要一种方法来了解“财产的属性”,希望您可以明白我的意思。
有些人会说:使用您的第一个实现(没有代理的实现,意味着问题中的第一个代码),但是使用for
.. of
循环来获取键名。我会说,我想使用这个确切的代码:
DOM.slide1.Box
获得此输出:
"#slide1 #Box"
为什么?为什么我在做什么?因为我需要一种在JavaScript中定义HTML类和ID的方法,所以在使用document.querySelector
时,生活变得更加轻松。另外,更改HTML文件中的类和ID名称的好处是,因此,当我更改HTML文件中的类和ID名称时,不再需要重构(重新)(重写)(更改)较新的文件。整个JavaScript文件中的类和ID名称。
解决方法
虽然代理可以做到这一点,但是有一种更简单的方法:首先将正确的字符串值放在DOM
的属性中。这仍然允许您根据需要访问它们:
const DOM = selectorHierarchy({
slide1: {
button: ".btn",box: "#box"
}
});
function selectorHierarchy(obj,ancestors = []) {
for (var key in obj)
if (typeof obj[key] == "string")
obj[key] = [...ancestors,obj[key]].join(" ");
else if (typeof obj[key] == "object")
selectorHierarchy(obj[key],[...ancestors,'#'+key]);
return obj;
}
console.log(DOM.slide1.box)
,
这是可能的。天真的方法是将代理递归地应用于每个对象,然后将私有属性与每个调用一起传递,将遍历字符串化为叶子。
概念证明:
const deepProxyAll = (obj,proxyObj) => {
for (const k in obj) {
if (typeof obj[k] === "object") {
obj[k] = deepProxyAll(obj[k],proxyObj);
}
}
return new Proxy(obj,proxyObj);
};
const proxyObj = {
get: (target,property,receiver) => {
if (!target.hasOwnProperty(property)) {
throw new Error(`property '${property}' does not exist on object`);
}
else if (typeof target[property] === "object" &&
typeof target[property] !== "null") {
target[property]._str = target._str ?
`${target._str} ${property}` : `#${property}`;
return target[property];
}
return target._str ? `${target._str} ${target[property]}`
: `#${target[property]}`;
}
};
const obj = {
slide1: {
button: ".btn",box: "#box",foobar: {bar: {quux: {garply: 42}}}
},test: "hello",};
const DOM = deepProxyAll(obj,proxyObj);
console.log(DOM.slide1.box);
console.log(DOM.slide1.foobar.bar.quux.garply);
console.log(DOM.test);
代理功能强大,它正试图改变对象属性访问的行为以适应各种突发奇想,但在采用这种方法作为核心设计之前,必须认真考虑好处是否值得其缺点。