【问题标题】:Constructor functions prototype enumerable?构造函数原型可枚举?
【发布时间】:2014-10-17 16:57:07
【问题描述】:

在阅读了一些帖子和文档后,我仍然不清楚可枚举属性的真正定义。继续前进,让我告诉你我在哪里感到困惑:

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

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 语句遍历一个可枚举的属性 对象,以任意顺序。对于每个不同的属性, 可以执行语句。

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

属性的所有权由属性是否直接属于对象而不属于其原型链来确定。

所以前面创建的原型并不是直接在myObject的实例上,而是包含在原型链中。为什么循环遍历每个键时都包含这个?

【问题讨论】:

  • 仅获取 myObj 的属性而不是原型,请执行 if(myObj.hasOwnProperty(key))。
  • 所以你不想在输出中包含'e'?
  • 如果你想为 myAlphabet 定义一个属性而不是在 myObject 上,你可以使用Object.defineProperty

标签: javascript


【解决方案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
}

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 2014-01-16
    • 2011-10-30
    • 1970-01-01
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多