js可列舉屬性和不可列舉屬性
我最近在學習vue的雙向繫結原理,用到一個了Object。defineProperty()方法。如果不太理解這個方法可以點選這裡。其中有個enumerable 配置項,如下
function
Person
()
{
this
。
name
=
“Ykx”
;
};
let
ykx
=
new
Person
();
Object
。
defineProperty
(
ykx
,
“sex”
,
{
value
:
“male”
,
//是否為列舉屬性
enumerable
:
false
});
console
。
log
(
ykx
);
for
(
let
p
in
ykx
)
{
console
。
log
(
“for。。。in遍歷 = ”
+
p
);
//name
}
console
。
log
(
“sex = ”
+
ykx
。
sex
)
那麼問題來了,什麼是可列舉屬性?
答
:
可列舉屬性是指那些內部 “可列舉” 標誌設定為 true 的屬性。對於透過直接的賦值和屬性初始化的屬性,該標識值預設為即為 true。但是對於透過 Object。defineProperty 等定義的屬性,該標識值預設為 false。
其中js中基本包裝型別的原型屬性是不可列舉的,如Object, Array, Number等。
可列舉的屬性可以透過for。。。in迴圈進行遍歷(除非該屬性名是一個Symbol),或者透過Object。keys()方法返回一個可列舉屬性的陣列。
下面是上述程式碼在谷歌瀏覽器中打印出來的log,淺色的sex就是不可列舉屬性。而for。。。in迴圈也只是打印出來了一個name,不可列舉的屬性也能直接獲取它的值。
我透過的。如果想遍歷物件的所有屬性,
Object.getOwnPropertyNames()
方法可實驗的出來的結論是,在物件屬性中標識不可列舉的屬性,一般不能為遍歷工具所遍歷,但是還是可以直接讀取以解決這個問題。這裡是他的api
function
Person
()
{
this
。
name
=
“Ykx”
;
};
let
ykx
=
new
Person
();
Object
。
defineProperty
(
ykx
,
“sex”
,
{
value
:
“male”
,
//是否為列舉屬性
enumerable
:
false
});
Object
。
getOwnPropertyNames
(
ykx
)。
forEach
(
function
(
key
)
{
console
。
log
(
key
)
//name ,sex
});
如果用Object。getOwnPropertyNames方法的話可以遍歷到它所有的屬性,包括可列舉和不可列舉的屬性。
上述三種獲取屬性的方法都有哪些區別?
for...in
遍歷物件的每一個可列舉屬性,包括原型鏈上面的可列舉屬性(js基本包裝型別的原型屬性是不能被遍歷因為是不可列舉的)。
function
Person
()
{
this
。
name
=
“Ykx”
;
};
Person
。
prototype
。
School
=
‘Tust’
;
Object
。
defineProperty
(
ykx
,
“sex”
,
{
value
:
“male”
,
//是否為列舉屬性
enumerable
:
false
});
let
ykx
=
new
Person
();
for
(
var
p
in
ykx
){
console
。
log
(
p
);
//name,School
}
上面的例子
說明能遍歷自己物件上的的可列舉屬性和還遍歷了原型上可列舉屬性。
Object.keys()
function
Person
()
{
this
。
name
=
“Ykx”
;
};
Person
。
prototype
。
School
=
‘Tust’
;
Object
。
defineProperty
(
ykx
,
“sex”
,
{
value
:
“male”
,
//是否為列舉屬性
enumerable
:
false
});
let
ykx
=
new
Person
();
Object
。
keys
(
ykx
)。
forEach
(
function
(
key
)
{
console
。
log
(
key
)
//name
});
上面只打印出來的name,
說明Object.keys方法只能遍歷自己的物件上的可列舉的屬性,不能遍歷自己原型上可列舉的屬性。
Object.getOwnPropertyNames()
function
Person
()
{
this
。
name
=
“Ykx”
;
};
Person
。
prototype
。
School
=
‘Tust’
;
Object
。
defineProperty
(
ykx
,
“sex”
,
{
value
:
“male”
,
//是否為列舉屬性
enumerable
:
false
});
let
ykx
=
new
Person
();
Object
。
getOwnPropertyNames
(
ykx
)。
forEach
(
function
(
key
)
{
console
。
log
(
key
);
//name,sex
});
上面的例子打印出來了name和sex,說明
它遍歷自身物件的所有屬性,包括可列舉不可列舉,但是原型上的屬性是無法遍歷的。
感謝您的閱讀!如有問題,歡迎指正~