【JS】《你不知道的JavaScript》 之 对象

简单基本类型(string、boolean、number、null、undefined)本身并不是对象,但是typeof null时会返回字符串‘object’。但实际上,null本身是基本类型。

原理是这样的。不同的对象在底层都表示二进制,在js中二进制前三位都为0的话会被判断为object,null的二进制表示全部为0,自然前三位也是0.所以执行typeof时会返回‘object’。

数组

数组也是对象,所以虽然每个下标都是整数,仍可以给数组添加属性

var myArr = ['foo', 42, 'bar']
myArr.baz = 'baz'
myArr.length     // 3
myArr.baz        // 'baz'

虽然添加了命名属性,数组的length值并未发生变化。

如果试图向数组添加一个属性,但是属性名‘看起来’像一个数字,那它会变成一个数值下标(因此会修改数组的内容而不是添加一个属性)

var myArr = ['foo', 42, 'bar']
myArr['3'] = 'baz'
myArr.length   // 4
myArr[3]       // 'baz'

属性描述符

var myObj = {a:2}
Object.getOwnPropertyDescriptor(myObj, 'a')
// {value: 2, writable: true, enumerable: true, configurable: true}

这个普通的对象属性对应的属性描述符不仅仅是一个2.它还包含另外三个特性:writable、enumerable和configurable。

在创建普通属性时属性描述符会使用默认值,可以使用Object.defineProperty()来添加一个新属性或者修改一个已有属性(如果是configurable)。

var myObj = {}
Object.defineProperty(myObj, 'a', {
    value: 3,
    configurable: true,
    enumerable: true,
    writable: true
})
myObj.a   // 2

除了defineProperty外还有defineProperties方法,差别如下:

Object.defineProperty(obj, prop, descriptor)
Object.defineProperties(obj, props)
  • writable决定是否可以修改属性的值
  • configurable决定属性是否可配置,只要属性是可配置的,就可以使用defineProperty()方法来修改属性描述符(把configurable修改为false是单向操作,无法撤销);configurable: false 还会禁止删除这个属性
  • enumerable决定的是该属性是否会出现在对象的属性枚举中。

不变性

  1. writable: false 和 configurable: false 就可以创建一个真正的常量属性。
  2. 若想禁止一个对象添加新属性并且保留已有属性,可以使用Object.preventExtensions()。
  3. Object.seal()会创建一个‘密封’的对象,这个方法实际上会在一个现有对象上调用Object.preventExtensions()并把所有现有属性标记为configurable: false。
  4. Object.freeze()会创建一个冻结对象,这个方法实际上会在一个现有对象上调用Object.seal()并把所有‘数据访问’属性标记为writable: false。

存在性

  • in 会检查对象及其原型链
  • hasOwnProperty 只会检查对象
  • propertyIsEnumerable会检查对象 并且 满足enumerable: true
  • Object.keys()会返回一个数组,包含所有可枚举属性
  • Object.getOwnPropertyNames()会返回一个数组,包含所有属性,无论他们是否可枚举

猜你喜欢

转载自blog.csdn.net/amyleeYMY/article/details/84246737