构造函数函数原型可枚举

Constructor functions prototype enumerable?

本文关键字:枚举 原型 函数 构造函数      更新时间:2023-09-26

在阅读了一些帖子和文档后,我仍然不清楚可枚举属性的真实定义。接下来,让我告诉你我困惑的地方:

我创建了一个构造函数并添加了一个原型。

var myAlphabet = function() {
  this.c = 5
  this.d = 6
}
myAlphabet.prototype = {
  e:7
}

现在,我使用新的关键字创建myAlphabet的一个新实例

var myObject = new myAlphabet();

使用for in循环,我想console.log myObject实例中的所有键(而不是原型中的键)。

for( key in myObj){
    console.log(key);
}

此日志:

'c'
'd'
'e'

根据。。循环文档:

用于。。in语句迭代对象,按任意顺序。对于每个不同的性质,语句可以被执行。

这让我相信原型是enumerable property。但是阅读Enumerable properties 的文档

财产的所有权取决于财产是否直接属于对象,而不是其原型链。

因此,前面创建的原型不是直接在myObject的实例上,而是包含在原型链中。当我循环每个键时,为什么它都包含这个?

当我循环每个键时,为什么它都包含这个?

它是通过设计javascript的对象原型来实现它们继承值的方式

就像你有类一样

class:base
{
    c:2
    d:3
}
base
{
    a:1
}

如果实例化myAlphabet类型的对象,它将具有属性a,b and c不同之处在于,在具有类的语言中,实例将"包含"所有值由它定义的和由父类定义的

instance of class
{
    a:1//because my parent told me so
    c:2
    d:3
}

在原型语言中,对象派生自对象,这意味着值不存在于实例本身,而是存在于充当父的实例上

object1
{
    prototype:object2//hidden from enumerator
    c:2
    d:3
    ...//when enumerating include all from prototype
}
object2
{
    prototype:null//hidden from enumerator
    a:1
    ...//when enumerating include all from prototype
}

因此,您实际上可以像使用分类语言一样维护继承主要的区别在于,继承是动态的。。并且这些值实际上存在于原型对象中,如果在从子alert(object1.a)读取时更改object2.a = new,它将从父new 获取新的更新值

如果您需要知道枚举属性是否驻留在从父对象中提取的对象本身中,则必须使用object1.hasOwnProperty(a)