我对为什么javascript以某种方式工作感到困惑。 如果我将Object设置为obj的变量。
如果我想列出对象中的所有键。
我会说
Object.keys(obj)
为什么不是
obj.keys()
如果我正在使用数组,它将是arr.pop() 那么,为什么不为obj.keys()使用相同的语法呢?同样,为什么它必须是Object.keys(obj)
对不起,我只是想学习语言的特殊性
答案 0 :(得分:4)
在keys
上放置Object.prototype
方法是可能,这样事情就可以按您期望的那样工作,但这不是一个好主意。
Object.prototype.keys = function() {
return Object.keys(this);
};
const obj = {
prop: 'val'
};
const keys = obj.keys();
console.log(keys);
使用对象键,问题在于对象通常可以具有任何种键。该对象甚至可能具有一个名为keys
的密钥。因此,例如:
const obj = {
name: 'building 1',
keys: 'foo'
}
在这里,如果您进行了obj.keys()
,则会得到一个TypeError
,因为keys
属性是直接在对象上引用的属性,而不是Object.prototype
方法
Object.prototype.keys = function() {
return Object.keys(this);
};
const obj = {
name: 'building 1',
keys: 'foo'
};
const keys = obj.keys();
console.log(keys);
因此,将用于获取对象所有键的方法放在静态Object
上,而不是Object.prototype
上的原型方法上,作为静态方法,以避免可能的名称冲突
通常,人们普遍希望数组具有数组特有的少数方法(例如push
),而没有其他 。数组不是通用对象-您几乎总是希望数组只有数组方法,并且数组几乎永远不会被添加任意键。 (如果您看到包含此代码的代码,则可能是值得重构的代码。)因此,使用数组时,像使用通用对象一样,数组方法几乎不会引起名称冲突。
因此,拥有Array.prototype.push
并没有什么害处,但是Object.prototype.keys
很容易引起问题。
答案 1 :(得分:0)
除了可能掩盖假设的keys()
方法的可能性之外,还有可能该值根本不是Object
的实例。
考虑以下示例:
// properly define your suggested method
Object.defineProperty(Object.prototype, 'keys', {
configurable: true,
writable: true,
value: function keys () { return Object.keys(this); }
})
const obj = { foo: 'bar', hello: 'world' };
console.log(obj instanceof Object);
// okay
console.log(obj.keys());
const value = Object.create(
null,
Object.getOwnPropertyDescriptors(obj)
);
console.log(value instanceof Object);
// existing approach still works
console.log(Object.keys(value));
// suggested approach fails
console.log(value.keys());