JavaScript中的自有和继承属性介绍

895 阅读3分钟

在JavaScript中,与其他编程语言如Java或Python相反,没有创建对象的模板(如类)概念。

每个JavaScript对象都链接到另一个名为prototype的对象,该对象从它那里继承属性。

在这篇文章中,我将描述自己的和继承的属性之间的区别。这是理解JavaScript略微不寻常的继承机制的一个好方法。

1.自有属性

自有属性是直接定义在对象上的属性。

让我们来定义一个有一个属性的普通JavaScript对象。

const myObject = {
  myProp: 'Value'
};
myObject.myProp; // => 'Value'

myObject 是一个普通的JavaScript对象。属性 是直接定义在 ,是一个myProp myObject自有属性

要列出一个对象的自身属性,可以使用内置的实用函数Object.getOwnPropertyNames(object)

让我们来列出myObject 的自有属性。

const myObject = {
  myProp: 'Value'
};
Object.getOwnPropertyNames(myObject); // => ['myProp']

Object.getOwnPropertyNames(myObject) 返回一个数组,有一个自己的属性名称:['myProp']

2.继承的属性

继承的属性是对象从原型对象继承的属性。

JavaScript中的每个对象都链接到一个对象,即原型,它从原型中继承属性。

让我们再次使用myObject 。这一次让我们直接访问一个你没有在myObject 上定义的属性。

const myObject = {
  myProp: 'Value'
};
myObject.toString; // => function() {...}

属性访问器myObject.toString ,评估为一个函数。

当JavaScript评估表达式myObject.toString ,首先,它试图在自己的属性中找到属性toString - 但是它找不到(myObject 只有一个自己的属性myProp )。然后JavaScript在myObject 的原型对象中寻找,最后找到一个属性toString

myObject 的继承属性toString ,相当于直接从原型对象中访问相同的属性。

const myObject = {
  myProp: 'Value'
};
const myObjectProto = Object.getPrototypeOf(myObject);
myObject.toString === myObjectProto.toString; // => true

其中Object.getPrototypeOf(object) 是一个返回对象原型的实用函数。

3.原型作为继承属性的来源

当我试图理解JavaScript中的原型继承时,我认为原型对象是一个复杂或特殊的上帝对象。但其实它要简单得多。

把原型对象看成是一个对象的继承属性的来源。

4.自己的与继承的

让我们稍微修改一下myObject ,并直接在其上定义一个方法toString

const myObject = {
  myProp: 'Value',
  toString() {
    return `[object MyObject]`;
  }
};
const myObjectProto = Object.getPrototypeOf(myObject);
myObject.toString === myObjectProto.toString; // => false

因为myObject 有一个自己的属性toString ,该对象不再从原型对象继承toString

当一个对象有一个自己的属性并继承了一个同名的属性时,自己的属性要优先于继承的属性。

如果一个自己的属性被删除,那么继承就会重新激活。

const myObject = {
  myProp: 'Value',
  toString() {
    return `[object MyObject]`;
  }
};
// Own properties
myObject.toString(); // => '[object MyObject]'
myObject.myProp;     // => 'Value'
delete myObject.toString;
delete myObject.myProp;
// Inherited property
myObject.toString(); // => '[object Object]'
// No inherited property
myObject.myProp;     // => undefined

第一个方法调用myObject.toString() ,使用自己的属性。然后delete myObject.toString 删除自己的属性。

第二个调用myObject.toString() ,即使删除了自己的属性toString ,也会使用从原型对象中继承的toString 属性。

然而,没有从原型继承的myProp 。当自己的道具myProp 从对象delete myObject.myProp 中被删除时,后来表达式myObject.myProp 评估为undefined

5.总结

一个JavaScript对象可以有自己的或继承的属性。

自己的属性意味着该属性是直接定义在对象上的。另一方面,继承的属性是指从原型对象上继承的属性。

了解自有属性和继承属性的区别是理解JavaScript原型继承的重要一步。