构造函数原型的可枚举属性是什么?

3

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

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

var myAlphabet = function() {
  this.c = 5
  this.d = 6
}

myAlphabet.prototype = {
  e:7
}

现在我使用new关键字创建了一个名为myAlphabet的新实例。
var myObject = new myAlphabet();

使用for-in循环,我想控制台记录myObject实例中所有键(不包括原型中的键)。
for( key in myObj){
    console.log(key);
}

这将记录日志:
'c'
'd'
'e'

根据for..in循环的文档:
for..in语句按任意顺序遍历对象的可枚举属性。对于每个不同的属性,可以执行语句。
这让我相信原型是一个可枚举属性。但阅读“可枚举属性”的文档时,我们可以看到:
属性的所有权是通过属性是否直接属于该对象而不是其原型链来确定的。
因此,早期创建的原型不直接在myObject实例上,而是包含在原型链中。当我遍历每个键时为什么会包括它?

要获取myObj的属性而不是原型,请使用if(myObj.hasOwnProperty(key)) - A1rPun
所以你不想在输出中包含'e'字符吗? - Prabhu Murthy
如果你想要为myAlphabet定义一个属性,但不是在myObject上,你可以使用Object.defineProperty - juvian
1个回答

1

当我循环每个键时,为什么会包括它?

这是 JavaScript 对象原型的设计,这种方式可以继承值。

同样的方式,如果你有类的话。

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

如果您实例化了一个名为myAlphabet的对象,它将具有属性a、b和c。与使用类的语言不同之处在于,实例将“包含”所有值,即由它自身定义的值和父类定义的值。请注意保留html标签。
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
}

所以你可以像使用类语言一样虚拟维护继承,主要区别在于继承是即时进行的...如果你改变object2.a = new,当你从子级读取alert(object1.a)时,它将从父级new中获取新的更新值,并且这些值实际上驻留在原型对象中。

如果您需要知道枚举属性是存在于对象本身还是被从父级获取,您必须使用object1.hasOwnProperty(a)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接