在 JavaScript 中使用点表示法时,调用(访问)(传递)(遍历)的每个元素的返回值

问题描述 投票:0回答:2

我想做这样的事情:

let DOM = {
   slide1: {
    button: ".btn",
    box: "#box"
   }
}

然后当我写下:

console.log(DOM.slide1.box);

我希望输出为

"#slide1 #box"

经过一番研究,我尝试使用 ES6 Proxy 对象,但问题并没有解决:

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 名称。

javascript ecmascript-6 es6-proxy javascript-proxy
2个回答
2
投票

虽然代理可以做到这一点,但还有一种更简单的方法:只需首先将正确的字符串值放入

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)

-1
投票

这是可能的。一种简单的方法是递归地将代理应用于每个对象,然后在每次调用时传递私有属性,将遍历字符串化到叶子。

概念证明:

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);

代理功能强大,并且很容易改变对象属性访问的行为以适应各种突发奇想,但在采用这种方法作为核心设计之前,请批判性地思考其好处是否值得其缺点。

© www.soinside.com 2019 - 2024. All rights reserved.