作者:顏海鏡
原文地址:http://yanhaijing.com/javascript/2015/05/08/member-of-object/
最近在回家的路上讀了尼古拉斯的新書《JavaScript面向?qū)ο缶?/a>》侈玄,發(fā)現(xiàn)自己對對象的屬性和方法不是很熟悉被冒,特別是es5新增的部分北滥,特寫此文總結(jié)一下,同時也與大家共勉荚板。
本文分為兩部分,分別介紹Object和Object.prototype上的一些常用方法。主要參考了MDN场梆,每個方法都給出了MDN的鏈接盔几。
前言
查看一個對象屬性的最好方法晴弃,不是去百度,也不是去google逊拍,而是用下面的方法(抄襲自 《DOM啟蒙》)
Object.getOwnPropertyNames(Object).sort().forEach(function (val) {console.log(val, '\n')});
上面的代碼會有如下的輸出:
如果不支持getOwnPropertyNames
的瀏覽器就用for in
吧肝匆,請自行解決。
Object
從上面的輸出中挑選出一些常用方法和屬性顺献,會得到下面的列表:
- create⑤
- defineProperty⑤
- defineProperties⑤
- getPrototypeOf⑤
- getOwnPropertyDescriptor⑤
- keys⑤
- getOwnPropertyNames⑤
- preventExtensions⑤
- isExtensible⑤
- seal⑤
- isSealed⑤
- freeze⑤
- isFrozen⑤
帶⑤的為es5新增的方法旗国。下面將會一一介紹上面的方法。
create
Object.create()
方法創(chuàng)建一個擁有指定原型和若干個指定屬性的對象注整。
Object.create(proto [, propertiesObject ])
-
proto
為新創(chuàng)建對象的原型對象能曾,設(shè)置為null
可創(chuàng)建沒有原型的空對象。 -
propertiesObject
包涵若干個屬性的描述符和defineProperties
的第二個參數(shù)一樣肿轨。
Object.create(Object.prototype, { a: { value: 1, writable: true, configurable: true } });
創(chuàng)建一個繼承自Object.prototype
的對象寿冕,有一個屬性a
,其可寫椒袍,可配置驼唱,不可枚舉,值為1驹暑。
更多詳情玫恳。
defineProperty
Object.defineProperty()
方法直接在一個對象上定義一個新屬性,或者修改一個已經(jīng)存在的屬性优俘, 并返回這個對象京办。
Object.defineProperty(obj, prop, descriptor)
descriptor 可包含4個屬性,如下:
-
configurable
當且僅當這個屬性描述符值為true
時帆焕,該屬性可能會改變惭婿,也可能會被從相應(yīng)的對象刪除。默認為false
。 -
enumerable true
當且僅當該屬性出現(xiàn)在相應(yīng)的對象枚舉屬性中财饥。默認為false
换吧。 -
value
屬性的值 -
writable
定義屬性值是否可寫。 -
get
一個給屬性提供getter
的方法钥星,如果沒有getter
則為undefined
式散。方法將返回用作屬性的值。默認為undefined
打颤。 -
set
同get
一起使用暴拄,功能互補。
其中value
和writable
一組编饺,get
和set
一組乖篷,不可同時出現(xiàn)。
// 顯式
Object.defineProperty(obj, "key", {
enumerable: false,
configurable: false,
writable: false,
value: "static"
});
上面給obj
對象定義了一個屬性key
透且,其不可枚舉撕蔼,不可配置,只讀秽誊,值為static
鲸沮。
更多詳情。
defineProperties
Object.defineProperties()
方法在一個對象上添加或修改一個或者多個自有屬性锅论,并返回該對象讼溺。
Object.defineProperties(obj, props)
更多詳情。
getPrototypeOf
Object.getPrototypeOf()
方法返回指定對象的原型(也就是該對象內(nèi)部屬性[[Prototype]]
的值)最易。
Object.getPrototypeOf(object)
可以用來獲取對象的原型怒坯。
Object.getPrototypeOf({}) === Object.prototype
// > true
在es5之前,要達到上面同樣的方法藻懒,只能使用constructor
剔猿。
({}).constructor.prototype === Object.prototype
// > true
但對于自定義的構(gòu)造函數(shù),如果復(fù)寫了prototype
嬉荆,可能導(dǎo)致獲取的constructor
不正確归敬,如何解決這個問題,可以看這篇文章鄙早。
更多詳情汪茧。
getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor()
返回指定對象上一個自有屬性對應(yīng)的屬性描述符。(自有屬性指的是直接賦予該對象的屬性蝶锋,不需要從原型鏈上進行查找的屬性)
Object.getOwnPropertyDescriptor(obj, prop)
可用來獲取或查看對象屬性的特性陆爽。
var obj = {a: 1};
Object.getOwnPropertyDescriptor(obj, 'a');
// > Object {value: 1, writable: true, enumerable: true, configurable: true}
更多詳情。
keys
Object.keys()
方法會返回一個由給定對象的所有可枚舉自身屬性的屬性名組成的數(shù)組扳缕,數(shù)組中屬性名的排列順序和使用for-in
循環(huán)遍歷該對象時返回的順序一致(兩者的主要區(qū)別是for-in
還會遍歷出一個對象,從其原型鏈上繼承到的可枚舉屬性)。
Object.keys(obj)
典型的用法如下:
var obj = {a: 1, b: 2};
console.log(Object.keys(obj));
// > ["a", "b"]
keys
可以用來代替原來的for in
循環(huán)躯舔,借助es5新增的數(shù)組方法驴剔,可提升代碼可讀性。
Object.keys(obj).forEach(function (val) {console.log(val)});
更多詳情粥庄。
getOwnPropertyNames
Object.getOwnPropertyNames()
方法返回一個由指定對象的所有自身屬性的屬性名(包括不可枚舉屬性)組成的數(shù)組丧失。
Object.getOwnPropertyNames(obj)
其和Object.keys
的區(qū)別就是能夠獲取自身的全部屬性,包括不可枚舉屬性惜互。
preventExtensions
Object.preventExtensions()
方法讓一個對象變的不可擴展布讹,也就是永遠不能再添加新的屬性。
Object.preventExtensions(obj)
需要注意的是训堆,不可擴展的對象的屬性通常仍然可以被刪除描验。
嘗試給一個不可擴展對象添加新屬性的操作將會失敗,在非嚴格模式下是靜默的坑鱼,在嚴格模式下會拋出TypeError異常膘流。
Object.preventExtensions
只能阻止一個對象不能再添加新的自身屬性,仍然可以為該對象的原型添加屬性鲁沥。
在 ECMAScript 5 中可擴展的對象可以變得不可擴展呼股,但反過來不行。
更多詳情画恰。
isExtensible
Object.isExtensible()
方法判斷一個對象是否是可擴展的(是否可以在它上面添加新的屬性)彭谁。
更多詳情。
seal
Object.seal()
方法可以讓一個對象密封允扇,并返回被密封后的對象马靠。密封對象是指那些不能添加新的屬性,不能刪除已有屬性蔼两,以及不能修改已有屬性的可枚舉性甩鳄、可配置性、可寫性额划,但可能可以修改已有屬性的值的對象妙啃。
Object.seal(obj)
密封一個對象會讓這個對象變的變?yōu)椴豢蓴U展的,且所有已有屬性會變的不可配置俊戳。屬性不可配置的效果就是屬性變的不可刪除揖赴,以及一個數(shù)據(jù)屬性不能被重新定義成為訪問器屬性,或者反之抑胎。但屬性的值仍然可以修改燥滑。
嘗試刪除一個密封對象的屬性或者將某個密封對象的屬性從數(shù)據(jù)屬性轉(zhuǎn)換成訪問器屬性,結(jié)果會靜默失敗或拋出TypeError異常(嚴格模式)阿逃。
更多詳情铭拧。
isSealed
Object.isSealed()
方法判斷一個對象是否是密封的(sealed)赃蛛。
更多詳情。
freeze
Object.freeze()
方法可以凍結(jié)一個對象搀菩。凍結(jié)對象是指那些不能添加新的屬性呕臂,不能修改已有屬性的值,不能刪除已有屬性肪跋,以及不能修改已有屬性的可枚舉性歧蒋、可配置性、可寫性的對象州既。也就是說谜洽,這個對象永遠是不可變的。該方法返回被凍結(jié)的對象吴叶。
Object.freeze(obj)
凍結(jié)對象是不可擴展的阐虚,密封的,同時期值屬性的writable
會被設(shè)置為false
晤郑,set
也將失效敌呈,總之會變?yōu)椴豢筛摹H魏螄L試修改該對象的操作都會失敗造寝,可能是靜默失敗磕洪,也可能會拋出異常(嚴格模式)。
isFrozen
Object.isFrozen()
方法判斷一個對象是否被凍結(jié)(frozen)诫龙。
更多詳情析显。
Object.prototype
Object.prototype
上的方法,都是實例方法签赃,必須在對象實例上調(diào)用谷异。
- hasOwnProperty
- isPrototypeOf⑤
- propertyIsEnumerable⑤
hasOwnProperty
hasOwnProperty()
方法用來判斷某個對象是否含有指定的自身屬性。
obj.hasOwnProperty(prop)
在沒有Object.keys
之前锦聊,借助hasOwnProperty
歹嘹,可以讓for in
達到類似的效果,代碼如下:
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
//過濾掉原型上的方法
}
}
更多詳情孔庭。
isPrototypeOf
isPrototypeOf()
方法測試一個對象是否存在于另一個對象的原型鏈上尺上。
prototype.isPrototypeOf(object)
更多詳情。
propertyIsEnumerable
propertyIsEnumerable()
方法返回一個布爾值圆到,表明指定的屬性名是否是當前對象可枚舉的自身屬性怎抛。
obj.propertyIsEnumerable(prop)
從原型鏈上繼承的屬性,所以該方法會返回false
芽淡。
如果對象沒有指定的屬性马绝,該方法返回false
。
更多詳情挣菲。
總結(jié)
除了上面介紹的方法富稻,還有一些實驗方法掷邦,和不常用的方法,可以在這里找到唉窃。