JavaScript 中的枚舉屬性 enumeration

先把總結(jié)寫在這里:

  1. JavaScript對象的屬性可分為可枚舉和不可枚舉柳骄,它是由屬性的 enumeration 值決定的夹界,true 為可枚舉,false為不可枚舉
  2. 原生構(gòu)造函數(shù)(Boolean, Number, String 等)的內(nèi)置屬性(例如 toSring可柿、 constructor等) 和 引擎內(nèi)置對象的屬性(Math 的 random 等) 一般是不可枚舉的,而自己定義的屬性(不管是原型上的還是自身的)一般是可枚舉的复斥。
  3. 屬性的枚舉性會影響以下四個方法的結(jié)果
    1) for...in
    2 )Object.keys()
    3) JSON.stringify()
    4) Object.assign()

小結(jié):

  • 這四個方法中,只有 for/in 是對所有可枚舉屬性(對象本身的可枚舉屬性目锭,以及從其構(gòu)造函數(shù)原型中繼承的可枚舉屬性),而其他三種是對自身可枚舉屬性才有效痢虹。
  • 而四個方法中又只有 Object.assign() 對 Symbol 屬性有效主儡,其他三種對 Symbol 都會過濾掉。
    這里做一個其他的小總結(jié):
  • 上面四個方法中糜值,其中Object.assign()無法正確拷貝get屬性和set屬性,而 JSON.stringify()對對象的方法寂汇、undefined值、get 屬性骄瓣、set屬性無效 。
  • 如果該參數(shù)不是對象榕栏,則會先轉(zhuǎn)成對象畔勤,然后返回臼膏。
    由于undefined和null無法轉(zhuǎn)成對象,所以如果它們作為(第一個)參數(shù)渗磅,就會報錯检访。有這兩種特性的方法是:
    Object.assign() 、 Object.setPrototypeOf()脆贵、Object.getPrototypeOf()



上面說了JavaScript對象的屬性是否可枚舉是 enumeration 的值決定的,那么enumeration是什么時候怎么去設(shè)置的呢卖氨?
enumeration 是 Object.defineProperty() 方法的一個參數(shù),下面來看看怎么去設(shè)置 一個屬性是否可枚舉筒捺。

var person = {
    name:'zhou',
    age: '12',
    sex: 'girl'
}

Object.defineProperty(person,'age',{
    enumerable:true,//可以被枚舉
});
Object.defineProperty(person,'sex',{
    enumerable:false,//可以被枚舉
})

for(var k in person){
    console.log(person[k])//a,可以被枚舉
}
//12
//zhou

如何設(shè)置是否可枚舉-- enumerable

由上面的點可以看出:
1.Object.defineProperty(obj, prop, descriptor)方法有三個參數(shù),每個參數(shù)各代表著
  第一個:目標屬性所在的對象系吭,
  第二個:目標屬性,放在字符串里颗品,
  第三個:目標屬性的行為,放在對象里躯枢;
2.enumerable為true表示可枚舉,enumerable為false表示不可枚舉锄蹂;
3.開發(fā)者自定義的對象person的所有屬性都是可枚舉的;

如何判斷是否可枚舉-- obj.propertyIsEnumerable()

在不知情的情況下败匹,如何判斷一個屬性是否可枚舉呢?obj.propertylsEnumerable()方法可以解決這個問題掀亩。

  1. 語法:obj.propertyIsEnumerable(prop)
  2. 定義:每個對象都有一個propertyIsEnumerable方法欢顷,表示指定的自身屬性是否可枚舉 (繼承屬性無效) ,返回一個布爾值(當對象沒有該指定屬性時也返回 false)。
  3. 用法:
    1)就上面的例子的使用
person.propertyIsEnumerable('name');//true
person.propertyIsEnumerable('age');//true
person.propertyIsEnumerable('sex');//false

2)引擎內(nèi)置對象的屬性不可枚舉

var o = {};
var a = [];
o.prop = 'is enumerable';
a[0] = 'is enumerable';
o.propertyIsEnumerable('prop')  // true
a.propertyIsEnumerable(0);  // true


Math.propertyIsEnumerable('random') // false
Object.propertyIsEnumerable('constructor') // false

從 用法1 和 用法2 可以看出用戶自定義屬性是可枚舉的(一般情況下自定義屬性都是可枚舉的抬驴,除非像 person.sex 經(jīng)過屬性描述符的修改),而瀏覽器內(nèi)置對象如 Math 的屬性是不可枚舉的布持。

3)原生構(gòu)造函數(shù)的內(nèi)置屬性不可枚舉,如Boolean, Number, String, Array, Date, Function, RegExp, Error, Object

var num = new Number();
for(var prop in num) {
    console.log(prop);
}

輸出為空题暖。for in 訪問的是所有可枚舉屬性捉超,這里輸出為空,說明Number中內(nèi)置的屬性是不可枚舉的唯绍,例如 toString() 方法拼岳。

4)自定義屬性一般為可枚舉屬性( 不管是自身屬性還是原始上的繼承屬性 )
說明:

  • 開發(fā)者自定義的屬性在一般情況下是可枚舉的
  • for /in 對所可以訪問到所有可枚舉屬性
  • obj.propertyIsEnumerable(prop) 只能訪問到 對象自身可枚舉屬性(對象自身添加的、構(gòu)造函數(shù)實例化的) 有效惜纸,對原始上的繼承屬性無效。
  • obj.hasOwnProperty(prop) 返回一個布爾值耐版,指示對象自身屬性中是否具有指定的屬性
  • Object.getOwnPropertyNames(obj) 返回一個由指定對象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol值作為名稱的屬性)組成的數(shù)組。
  • Object.keys() 方法會返回一個由一個給定對象的自身可枚舉屬性組成的數(shù)組粪牲。
//構(gòu)造函數(shù)
function People() {
  this.hobby = 'eat';
}
People.prototype.showHooby = function() {};

//繼承
function Coder() {
  this.love = function method() { return 'coder‘s love is codeing'; };
}
Coder.prototype = new People;
Coder.prototype.constructor = Coder;

//實例
var c = new Coder();
c.age = '24';
//打印出實例
console.dir(c)

我們來看看打印出來的實例對象蛾魄,看看哪些屬性是自身的,哪些屬性是在原型上的


image.png

for/in 來訪問 o 對象滴须,看看哪些屬性是可枚舉的:

for(var prop in c){
    console.log(prop)
}
// love
// age
// hobby
// constructor
// showHooby 

自定義屬性都可枚舉舌狗,不管是自身屬性還是原始上的繼承屬性

怎么過濾出自身可枚舉屬性呢痛侍?就可以用 obj.propertyIsEnumerable() , Object.getOwnPropertyNames(), obj.hasOwnProperty, Object.keys() 方法啦

// obj.propertyIsEnumerable()  --- 先找出*所有可枚舉屬性*,再找出自身的可枚舉屬性
for(var prop in c){
    if(c.propertyIsEnumerable(prop)) console.log(prop)
}
// love
// age


// 或者 obj.hasOwnProperty() --- 先找出*所有可枚舉屬性*主届,再找出自身屬性
for(var prop in c){
    if(c.hasOwnProperty(prop)) console.log(prop)
}
// love
// age


// 或者 Object.getOwnPropertyNames() --- 先找出*所有自身屬性*的屬性名,再找出可枚舉的
var cName = Object.getOwnPropertyNames(c);
for(var prop in cName){
    console.log(cName[prop])
}
// love
// age


// 或者 Object.keys() --- 直接找出自身可枚舉屬性
Object.keys(c) 
//["love", "age"]



參考鏈接:
MDN:Object
MDN: 屬性的可枚舉性和所有權(quán)

自己總結(jié)了大半天君丁,然后看到阮大神比較全的一篇:
阮一峰:屬性的可枚舉與遍歷

上面說到關(guān)于對象屬性“枚舉性”的多種方法,這里放放上一張這些屬性微妙差別的對比圖:


屬性的可枚舉性和所有權(quán)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绘闷,一起剝皮案震驚了整個濱河市较坛,隨后出現(xiàn)的幾起案子印蔗,更是在濱河造成了極大的恐慌华嘹,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耙厚,死亡現(xiàn)場離奇詭異强挫,居然都是意外死亡纠拔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門泛豪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人诡曙,你說我怎么就攤上這事〖勐保” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵床嫌,是天一觀的道長。 經(jīng)常有香客問我胸私,道長,這世上最難降的妖魔是什么岁疼? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任哈打,我火速辦了婚禮,結(jié)果婚禮上支鸡,老公的妹妹穿的比我還像新娘椭住。我一直安慰自己,他們只是感情好函荣,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布扳肛。 她就那樣靜靜地躺著乘碑,像睡著了一般挖息。 火紅的嫁衣襯著肌膚如雪兽肤。 梳的紋絲不亂的頭發(fā)上绪抛,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天电禀,我揣著相機與錄音,去河邊找鬼尖飞。 笑死,一個胖子當著我的面吹牛政基,可吹牛的內(nèi)容都是我干的贞铣。 我是一名探鬼主播沮明,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼荐健!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起江场,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扛稽,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體在张,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年啄骇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缸夹。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖螺句,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蛇尚,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布取劫,位于F島的核電站研侣,受9級特大地震影響炮捧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜咆课,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望傀蚌。 院中可真熱鬧基显,春花似錦撩幽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽榨惰。三九已至,卻和暖如春静汤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虫给。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留抹估,地道東北人。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓药蜻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親语泽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容