JS原生引用类型解析1-Object类型

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!)
(注2:更多内容请查看我的目录。)

1. 简介

Object是ECMAScript中使用最多的一个类型,所有引用类型默认都继承Object,这种既成通过原型链实现,所有对象从Object.prototype继承方法和属性,尽管它们可能被覆盖。

例如,其他构造函数的原型将覆盖constructor属性并提供自己的toString()方法。Object原型对象的更改将传播到所有对象,除非受到这些更改的属性和方法将沿原型链进一步覆盖。

所以我们需要对Object的内置属性和方法有一个清晰的认识。

2. Object构造函数的使用

前面我们讲过创建对象的各种方法。其中,Object构造函数为给定值创建一个对象包装器。

如果给定值是null或undefined,将会创建并返回一个空对象。否则,将返回一个与给定值对应类型的对象。

当以非构造函数形式被调用时,Object 等同于 new Object()。

3. Object构造函数的属性与方法

我们用Object.getOwnPropertyNames()方法获取Object构造函数的所有属性与方法。

Object.getOwnPropertyNames(Object);
// (23) ["length", "name", "prototype", "assign", "getOwnPropertyDescriptor", "getOwnPropertyDescriptors", "getOwnPropertyNames", "getOwnPropertySymbols", "is", "preventExtensions", "seal", "create", "defineProperties", "defineProperty", "freeze", "getPrototypeOf", "setPrototypeOf", "isExtensible", "isFrozen", "isSealed", "keys", "entries", "values"]

发现一共有23个属性和方法。

3.1 Object构造函数的属性

Object.length
长度为1

Object.name
名称为"Object"

Object.prototype
指向Object构造函数的原型,可以为所有 Object 类型的对象添加属性。

3.2 Object构造函数的方法

Object.assign()
用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,复制过程对已存在的属性会进行覆盖。它将返回目标对象。

var obj = {
    a: 0,
    d: 6
}
var obj1 = {
    a: 1,
    b: 2
}
Object.defineProperty(obj1, 'c', {
    value: 3,
    enumerable: false
});
var obj2 = Object.assign(obj, obj1);
console.log(obj);  // {a: 1, d: 6, b: 2}
console.log(obj2); // {a: 1, d: 6, b: 2}

Object.create()
使用指定的原型对象及其属性去创建一个新的对象。(具体可参考JS入门难点解析10-创建对象

Object.defineProperty()
直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。(具体可参考JS入门难点解析13-属性描述符,数据属性和访问器属性

Object.defineProperties()
直接在一个对象上定义多个新属性,或者修改一个对象的现有属性,并返回这个对象。

Object.entries()
该方法接收一个对象为参数,返回该对象自身可枚举属性的键值对数组,其排列与使用for...in...循环循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)。(具体可参考JS常用方法整理-遍历对象

Object.freeze()
可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。(具体可参考JS入门难点解析13-属性描述符,数据属性和访问器属性

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

Object.getOwnPropertyNames()
返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。(具体可参考JS常用方法整理-遍历对象

Object.getOwnPropertySymbols()
回一个给定对象自身的所有 Symbol 属性的数组。

Object.getPrototypeOf()
返回指定对象的原型(内部[[Prototype]]属性的值)。

Object.is()
判断两个值是否是相同的值。如果下列任何一项成立,则两个值相同:

  • 两个值都是 undefined
  • 两个值都是 null
  • 两个值都是 true 或者都是 false
  • 两个值是由相同个数的字符按照相同的顺序组成的字符串
  • 两个值指向同一个对象
  • 两个值都是数字并且
    • 都是正零 +0
    • 都是负零 -0
    • 都是 NaN
    • 都是除零和NaN外的其它同一个数字

这种相等性判断逻辑和传统的 == 运算符所用的不同,== 运算符会对它两边的操作数做隐式类型转换(如果它们类型不同),然后才进行相等性比较,(所以才会有类似 "" == false 为 true 的现象),但 Object.is 不会做这种类型转换。

这与 === 运算符也不一样。=== 运算符(和 == 运算符)将数字值-0和+0视为相等,并认为Number.NaN不等于NaN

Object.is('foo', 'foo');     // true
Object.is(window, window);   // true

Object.is('foo', 'bar');     // false
Object.is([], []);           // false

var test = { a: 1 };
Object.is(test, test);       // true

Object.is(null, null);       // true

// 特例
Object.is(0, -0);            // false
Object.is(-0, -0);           // true
Object.is(NaN, 0/0);         // true

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

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

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

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

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

Object.seal()
让一个对象密封,并返回被密封后的对象。密封对象将会阻止向对象添加新的属性,并且会将所有已有属性的可配置性(configurable)置为不可配置(false),即不可修改属性的描述或删除属性。但是可写性描述(writable)为可写(true)的属性的值仍然可以被修改。

Object.setPrototypeOf()
设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或null
注意:Object.setPrototypeOf()是ECMAScript 6最新草案中的方法,相对于Object.prototype._proto_,它被认为是修改对象原型更合适的方法。但是,如果你关心性能,你应该避免设置一个对象的[[Prototype]]。相反,你应该使用 Object.create()来创建带有你想要的[[Prototype]]的新对象。

Object.values()
返回一个给定对象自己的所有可枚举属性值的数组,值的顺序与使用for-in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。

4. Object原型对象的属性与方法

我们用Object.getOwnPropertyNames()方法获取Object原型对象的所有属性与方法。

Object.getOwnPropertyNames(Object.prototype);
// (12) ["constructor", "__defineGetter__", "__defineSetter__", "hasOwnProperty", "__lookupGetter__", "__lookupSetter__", "isPrototypeOf", "propertyIsEnumerable", "toString", "valueOf", "__proto__", "toLocaleString"]

发现一共有12个属性和方法。

4.1 Object原型对象的属性

Object.prototype.constructor
指向构造函数Object

Object.prototype._proto_
对于Object.prototype,其值为null,以此避免无限循环。构造函数新建实例对象时,在实例对象调用会指向实例对象的原型对象。该特性为非标准特性,尽量不要使用。

4.2 Object原型对象的方法

Object.prototype.hasOwnProperty()
该方法会返回一个布尔值,指示对象自身属性(非原型链继承)中是否具有指定的属性。

Object.prototype.isPrototypeOf()
该方法返回一个布尔值,表示指定的对象是否在本对象的原型链中。

Object.prototype.PropertyIsEnumerable()
该方法返回一个布尔值,判断指定属性是否可枚举。

Object.prototype.toString()
如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中type是对象的类型。对于Object.prototype.toString(),其值为"[object Object]"。

Object.prototype.toLocalString()
返回一个该对象的字符串表示。此方法被用于派生对象为了特定语言环境的目的(locale-specific purposes)而重载使用。绝大多数情况下和Object.prototype.toString()一样。

Object.prototype.valueOf()
返回值为该对象的原始值。

5. Object实例对象的属性与方法

我们用Object.getOwnPropertyNames()方法获取Object实例对象的所有属性与方法。

var obj = new Object({a:1,b:2});
Object.getOwnPropertyNames(obj);  // ["a", "b"]

传入属性的key值即为其属性。但是有一点要注意的是,此时可以使用obj._proto指向其原型对象,这个_proto属性按照《JAvaScript高级程序设计》一书和我们前面的分析,按道理应该是实例属性,但这里却并不是(或者是虽然是,但是无法被Object.getOwnPropertyNames()方法列出,如果这样的话,也说得通),不知道底层具体是如何来实现的,如果是共享自Object原型,为什么每一个实例的值都是不同的。(如果有懂这块的同学,还请不吝赐教。)

参考

MDN-Object

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

推荐阅读更多精彩内容

  •   面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意...
    霜天晓阅读 2,098评论 0 6
  • “hi,亲爱的,今天是个特殊的日子?” “嗯……啥日子?老婆,生日了吗?结婚纪念日哪一天来着?丈母娘生日啦!?双1...
    末的sara阅读 355评论 0 2
  • 2018年到了,祝大家元旦快乐! 日程安排: 12点一过就急着换上了新年的1月份手帐页面,日程安排页还是手绘,用了...
    德鲁喵肥美多脂阅读 1,154评论 2 2
  • 我记得曾经有一个人总喜欢给我说着一些我似懂非懂的道理。影响中我记得她很多的话语,但又好像只记得她唯一的一句话。成长...
    逆流成长阅读 246评论 0 1