JS - 属性路径访问以及 ES6 的计算属性名

发布时间 2023-09-24 00:20:43作者: Himmelbleu

前言

今天学习 jointjs 框架,在阅读官方文档时碰到了一个写法让我很奇怪的写法,如下所示。通过查询资料得知这是一种使用语言特性的编码约定或模式,称为 属性路径访问

file:[jointjs - elementTools.Control]
class RadiusControl extends elementTools.Control {

    protected getPosition(view: dia.ElementView): dia.Point {
        const { model } = view;
        lit:[const radius = model.attr(['body', 'ry']) || 0;]:lit
        return { x: 0, y: radius };
    }

    protected setPosition(view: dia.ElementView, coordinates: dia.Point): void {
        const { model } = view;
        const { height } = model.size();
        const radius = Math.min(Math.max(coordinates.y, 0), height / 2);
        lit:[model.attr(['body'], { rx: radius, ry: radius  });]:lit
    }

    protected resetPosition(view): void {
        const { model } = view;
        const { defaultRadius = 0 } = this.options;
        lit:[model.attr(['body'], { rx: defaultRadius, ry: defaultRadius });]:lit
    }
}

使用数组来构建属性路径,当需要根据条件或变量的值来确定要访问的属性时,可以避免通过传统的 . 的方式获取对象属性路径,从而获取值。在许多 JavaScript 库和框架中都被广泛使用,用于处理配置、数据结构等方面的动态属性访问需求。

复习 - 计算属性名

在 ES6 中,有一种对象访问方式叫作 “计算属性名”,这种访问对象属性的路径也非常有用。假如下面有一个对象:

file:[demo.js]
const person = {
    firstName: "John",
    lastName: "Doe"
};

而在使用计算属性名的情况下,你可以在方括号内使用表达式来定义属性名。这个表达式的结果将被用作属性的名称。例如:

file:[demo.js]
const propertyName = "age";
const person = {
    name: "John",
    [propertyName]: 30
};

计算属性名的主要优势在于你可以根据需要动态地定义属性名,而不必事先知道属性名的确切值。这对于处理动态数据或根据条件设置属性名非常有用。例如,你可以在循环中使用计算属性名来创建一组属性:

file:[demo.js]
const fruits = ["apple", "banana", "cherry"];
const fruitObjects = {};

for (const fruit of fruits) {
    fruitObjects[fruit] = "available";
}

// { apple: "available", banana: "available", cherry: "available" }

在这个示例中,我使用循环和计算属性名来动态创建了一个对象,该对象的属性名来自数组 fruits 中的元素。

属性路径访问

file:[demo2.js]
const person = {
  address: {
    city: "New York"
  },
  one: { two: { three: "one-two-three" } }
};

function getProperty(obj, path) {
  let propertyValue = obj;
  for (let i = 0; i < path.length; i++) {
    const propertyName = path[i];
    propertyValue = propertyValue[propertyName];
  }
  return propertyValue;
}

console.log(getProperty(person, ["address", "city"])); // New York
console.log(getProperty(person, ["one", "two", "three"])); // one-two-three

不管你的对象路径有多深,都可以通过数组构建出路径出来,并获取到最终想要的值。