在阅读了几篇文章和文档之后,我仍然不清楚可枚举属性的真正定义。接下来,让我告诉你我困惑的地方:
我创建了一个构造函数并添加了一个原型。
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的实例上,它包含在原型链中。当我遍历每个键时,为什么包括这个?
答案 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)