前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS原生引用类型解析1-Object类型

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

作者头像
love丁酥酥
发布2018-08-27 15:39:39
2.1K0
发布2018-08-27 15:39:39
举报
文章被收录于专栏:coding for love

(注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构造函数的所有属性与方法。

代码语言:javascript
复制
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()

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

代码语言:javascript
复制
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

代码语言:javascript
复制
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原型对象的所有属性与方法。

代码语言:javascript
复制
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实例对象的所有属性与方法。

代码语言:javascript
复制
var obj = new Object({a:1,b:2});
Object.getOwnPropertyNames(obj);  // ["a", "b"]

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

参考

MDN-Object

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.02.23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 简介
  • 2. Object构造函数的使用
  • 3. Object构造函数的属性与方法
    • 3.1 Object构造函数的属性
      • 3.2 Object构造函数的方法
      • 4. Object原型对象的属性与方法
        • 4.1 Object原型对象的属性
          • 4.2 Object原型对象的方法
          • 5. Object实例对象的属性与方法
          • 参考
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档