构造函数原型可枚举?

时间:2014-10-17 16:57:08

标签: javascript

在阅读了几篇文章和文档之后,我仍然不清楚可枚举属性的真正定义。接下来,让我告诉你我困惑的地方:

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

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

myAlphabet.prototype = {
  e:7
}

现在我使用new关键字

创建myAlphabet的新实例
var myObject = new myAlphabet();

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

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

此日志:

'c'
'd'
'e'

根据for..in循环文档:

  

for..in语句遍历一个的可枚举属性   对象,以任意顺序。对于每个不同的财产,   语句可以执行。

这使我相信原型是enumerable property。但请阅读Enumerable properties

的文档
  

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

因此,之前创建的原型不直接在myObject的实例上,它包含在原型链中。当我遍历每个键时,为什么包括这个?

1 个答案:

答案 0 :(得分:1)

  

为什么在循环每个键时包含这个?

设计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
}

所以你几乎可以保持继承,就像使用分类语言一样 主要区别在于,继承是在运行中进行的..如果您在从子object2.a = new读取时更改alert(object1.a),则实际上会将值保留在原型对象中,它将从中获取新的更新值父new

如果您需要知道枚举属性是否位于从父级获取的对象中,您必须使用object1.hasOwnProperty(a)