细说JavaScript中对象的属性和方法

作者:颜海镜
原文地址:http://yanhaijing.com/javascript/2015/05/08/member-of-object/

最近在回家的路上读了尼古拉斯的新书《JavaScript面向对象精要》,发现自己对对象的属性和方法不是很熟悉,特别是es5新增的部分,特写此文总结一下,同时也与大家共勉。

本文分为两部分,分别介绍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()方法创建一个拥有指定原型和若干个指定属性的对象。

Object.create(proto [, propertiesObject ])
  • proto为新创建对象的原型对象,设置为null可创建没有原型的空对象。
  • propertiesObject包涵若干个属性的描述符和defineProperties的第二个参数一样。
Object.create(Object.prototype, { a: { value: 1, writable: true, configurable: true } });

创建一个继承自Object.prototype的对象,有一个属性a,其可写,可配置,不可枚举,值为1。

更多详情

defineProperty

Object.defineProperty()方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。

Object.defineProperty(obj, prop, descriptor)

descriptor 可包含4个属性,如下:

  • configurable当且仅当这个属性描述符值为true时,该属性可能会改变,也可能会被从相应的对象删除。默认为false
  • enumerable true当且仅当该属性出现在相应的对象枚举属性中。默认为false
  • value属性的值
  • writable定义属性值是否可写。
  • get一个给属性提供getter的方法,如果没有getter则为 undefined。方法将返回用作属性的值。默认为undefined
  • setget一起使用,功能互补。

其中valuewritable一组,getset一组,不可同时出现。

// 显式
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()方法返回指定对象的原型(也就是该对象内部属性[[Prototype]]的值)。

Object.getPrototypeOf(object)

可以用来获取对象的原型。

Object.getPrototypeOf({}) === Object.prototype
// > true

在es5之前,要达到上面同样的方法,只能使用constructor

({}).constructor.prototype === Object.prototype
// > true

但对于自定义的构造函数,如果复写了prototype,可能导致获取的constructor不正确,如何解决这个问题,可以看这篇文章

更多详情

getOwnPropertyDescriptor

Object.getOwnPropertyDescriptor()返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)

Object.getOwnPropertyDescriptor(obj, prop)

可用来获取或查看对象属性的特性。

var obj = {a: 1};
Object.getOwnPropertyDescriptor(obj, 'a');
// > Object {value: 1, writable: true, enumerable: true, configurable: true}

更多详情

keys

Object.keys()方法会返回一个由给定对象的所有可枚举自身属性的属性名组成的数组,数组中属性名的排列顺序和使用for-in循环遍历该对象时返回的顺序一致(两者的主要区别是for-in还会遍历出一个对象,从其原型链上继承到的可枚举属性)。

Object.keys(obj)

典型的用法如下:

var obj = {a: 1, b: 2};
console.log(Object.keys(obj));
// > ["a", "b"]

keys可以用来代替原来的for in循环,借助es5新增的数组方法,可提升代码可读性。

Object.keys(obj).forEach(function (val) {console.log(val)});

更多详情

getOwnPropertyNames

Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性)组成的数组。

Object.getOwnPropertyNames(obj)

其和Object.keys的区别就是能够获取自身的全部属性,包括不可枚举属性。

preventExtensions

Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。

Object.preventExtensions(obj)

需要注意的是,不可扩展的对象的属性通常仍然可以被删除。

尝试给一个不可扩展对象添加新属性的操作将会失败,在非严格模式下是静默的,在严格模式下会抛出TypeError异常。

Object.preventExtensions只能阻止一个对象不能再添加新的自身属性,仍然可以为该对象的原型添加属性。

在 ECMAScript 5 中可扩展的对象可以变得不可扩展,但反过来不行。

更多详情

isExtensible

Object.isExtensible()方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。

更多详情

seal

Object.seal()方法可以让一个对象密封,并返回被密封后的对象。密封对象是指那些不能添加新的属性,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性,但可能可以修改已有属性的值的对象。

Object.seal(obj)

密封一个对象会让这个对象变的变为不可扩展的,且所有已有属性会变的不可配置。属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。

尝试删除一个密封对象的属性或者将某个密封对象的属性从数据属性转换成访问器属性,结果会静默失败或抛出TypeError异常(严格模式)。

更多详情

isSealed

Object.isSealed()方法判断一个对象是否是密封的(sealed)。

更多详情

freeze

Object.freeze()方法可以冻结一个对象。冻结对象是指那些不能添加新的属性,不能修改已有属性的值,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性的对象。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。

Object.freeze(obj)

冻结对象是不可扩展的,密封的,同时期值属性的writable会被设置为falseset也将失效,总之会变为不可更改。任何尝试修改该对象的操作都会失败,可能是静默失败,也可能会抛出异常(严格模式)。

isFrozen

Object.isFrozen()方法判断一个对象是否被冻结(frozen)。

更多详情

Object.prototype

Object.prototype上的方法,都是实例方法,必须在对象实例上调用。

  • 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

更多详情

总结

除了上面介绍的方法,还有一些实验方法,和不常用的方法,可以在这里找到。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容