javascript 基于同一对象的另一个特性的值计算对象特性

d7v8vwbk  于 2023-06-04  发布在  Java
关注(0)|答案(4)|浏览(169)

我需要找出obj对象中“name”的值。不调用函数怎么能找到它呢?
我只想使用obj.isActive而不是obj.isActive()

let obj = {
  name: "X Æ A-12 Musk",
  isActive: function () {
    return this.name.length > 4;
  },
};

// and after a while I need to check if is active:

console.log(obj);

// { 
//   name: 'X Æ A-12 Musk',
//   isActive: [Function: isActive]  <--------- NOT COOL ! 
// }

如果使用IFEE:

let obj = {
  name: "X Æ A-12 Musk",
  isActive: (function () {
    return this.name.length > 4;
  })(),
};

我得到:

return this.name.length > 4;
                ^
TypeError: Cannot read properties of undefined (reading 'length')
j9per5c4

j9per5c41#

如果你不想把isActive作为一个函数调用,你可以使用getter

const obj = {
  name: "X Æ A-12 Musk",
  get isActive () {
    return this.name.length > 4;
  },
};

console.log(obj.isActive);
wlwcrazw

wlwcrazw2#

与雷的回答类似,下面这样的情况如何:

let obj = {
    name: "test"
};

Object.defineProperty(obj, "isActive", {
    get: function() {
        return obj.name.length > 3;
    }
});

console.log(obj.isActive); // Output: true

如果它有帮助,并且你经常使用它,你可以创建一个helper函数:

function defineIsActive(object, condition) {
    
    Object.defineProperty(obj, "isActive", {
        get: function() {
            return condition
        }
    });
}

let obj = {
  name: 'test'
}

// And simply use it like so:
defineIsActive(obj, obj.name.length > 3)

console.log(obj.isActive)
zqry0prt

zqry0prt3#

我无法向该对象添加更多属性
您可以创建由原始对象原型化的 Package 器对象,并在前者中定义getter。

let obj = {
  name: "X Æ A-12 Musk",
  isActive: function () {
    return this.name.length > 4;
  },
};

function makeWrapper (obj) {
  let wrapper = Object.create(obj);
  Object.defineProperty(wrapper, 'isActive', {
    get () { return obj.isActive(); },
    enumerable: true
  });
  return wrapper;
}

let obj2 = makeWrapper(obj);
console.log(obj2);
q43xntqr

q43xntqr4#

从您的问题中还不清楚为什么可以执行IIFE而不能执行getter,但这里有一些其他潜在的解决方法。

1.使用Proxy拦截属性访问器:

如果你不能修改对象本身,你可以把它 Package 在一个Proxy中,然后把代理传递给库。

let obj = {
  name: "X Æ A-12 Musk",
  isActive: function () {
    return this.name.length > 4;
  },
};

const proxy = new Proxy(obj, {
  get(target, prop) {
    if (prop === 'isActive') {
      return target?.isActive?.();
    }
    return target[prop]
  }
});

console.log(proxy.isActive); // true
console.log(proxy.name); // "X Æ A-12 Musk"
console.log(proxy);
/*
{
  "name": "X Æ A-12 Musk",
  "isActive": true
}
*/

这可以被推广到调用任何getter函数,如果它存在于目标上:

let obj = {
  name: "X Æ A-12 Musk",
  isActive: function () {
    return this.name.length > 4;
  },
};

const proxy = new Proxy(obj, {
  get(target, prop) {
    const x = target[prop];
    return typeof x === 'function' ? target[prop]() : x;
  }
});

console.log(proxy.isActive); // true
console.log(proxy.name); // "X Æ A-12 Musk"
console.log(proxy);
/*
{
  "name": "X Æ A-12 Musk",
  "isActive": true
}
*/

注意:我在这里调用target[prop]()而不是x(),因为调用不关联的函数x()具有可能产生错误或意外结果的作用域影响(这也是导致IIFE崩溃的问题)。

2.使用Object.defineProperty建立getter。

同样,我不清楚为什么不能直接在对象字面量上放置getter,所以我也不知道这是否可行。

let obj = {
  name: "X Æ A-12 Musk",
  isActive: function() {
    return this.name.length > 4;
  },
};

Object.defineProperty(obj, "isActive", {
  get() {
    return this.name.length > 4
  }
})

console.log(obj);
/*
{
  "name": "X Æ A-12 Musk",
  "isActive": true
}
*/

相关问题