JavaScript 对象

JavaScript 对象 Object 是一系列属性的集合;每个属性都是一个键值对,key 的类型为字符串,value 可以为任何类型

创建对象

  • {}:对象字面量方式
  • new Object():构造函数
    • 输入参数为空,或者nullundefined会创建返回一个空对象;
    • 输入参数为对象,则直接返回该对象,var obj = {a: 1}; obj === new Object(obj);// true
    • 传入参数为原始类型,则返回该值的包装类;
    • 通过构造函数与字面量写法是等价的;
  • Object.create(proto[, propertiesObject]):创建一个对象,并指定对象的原型
    • proto:新创建对象的原型,可以为null或非基本类型包装对象以外的对象
    • propertiesObject:可选参数,详细参考对象属性模型

```JS 字面量初始化 // 属性/函数简写 const a = 1; const b = 'string'; const c = {}; const o = { a, b, c, add(a, b) { return a + b; }, }

// 计算属性(ES2015) const firstName = 'Jordan'; const lastName = 'Mike';

const player = {

} console.log(player); // {Mike Jordan Team: 'Bulls'}

// getter setter方法 const o = { logs: [], get log() { return this.logs; }, set log(value) { this.logs.push(value); } } o.log = 'do job a'; o.log = 'do job b'; console.log(o.log); // ["do job a", "do job b"]


```JS
const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

const me = Object.create(person);

const o = Object.create(Object.prototype, {
  foo: {
    writable: true,
    configurable: true,
    value: 'hello'
  },
  bar: {
    configurable: false,
    get: function() { return 10; },
    set: function(value) {
      console.log('Setting `o.bar` to', value);
    }
  }
});

对象属性模型

ECMAScript5 对对象的属性都提出了一个精确的模型描述,每个对象属性都有一个属性描述符对象,用来保存对象属性的描述,称为元信息。

查看对象属性元信息:可以通过Object.getOwnPropertyDescriptor(obj, prop)方法来获取

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

属性描述符有两种形式,数据描述符和存取描述符,一个描述符只能是其中一种,不能同时是两者:

  • 数据描述符:有具体值的属性
    • value:属性的值,默认undefined
    • writable:表示value的值是否可以改变(是否可以被赋值),默认false
    • enumerable:表示属性是否可枚举,默认false;详见对象属性遍历
    • configurable:表示属性是否可以配置,默认false;如果为false
      • 不可以使用delete删除该属性
      • 除了valuewritable之外的元信息都不能修改
  • 存取描述符:由gettersetter函数描述的属性
    • get:属性的取值函数,默认undefined
    • set:属性的赋值函数,默认undefined
configurable enumerable value writable get set
数据描述符 可以 可以 可以 可以 不可以 不可以
存取描述符 可以 可以 不可以 不可以 可以 可以

修改/添加对象属性元信息:

  • Object.defineProperty(object, propertyName, attributesObject)
  • Object.defineProperties(object, attributesObject)
var o = Object.defineProperty({}, 'a', {
  value: 1,
  writable: true,
  enumerable: true,
  configurable: true
});

Object.defineProperties({}, {
  a: {
    value: 1,
    writable: true,
    enumerable: true,
    configurable: true
  },
  b: {
    get:function() {
      return this.a * 2;
    }
  },
});
  • 设置get/set属性后不能将writable设置为false,也不能设置value,否则会报错;
  • enumerableenumerableconfigurable默认都为false

对象属性遍历

  • 可枚举属性遍历
    • for in:访问对象节对象自身及对象原型链上所有enumerable: true的属性,需要使用hasOwnProperty过滤原型链属性
    • Object.keys(object):获取对象自身包含的enumerable: true的属性的字符串数组
      • 仅包含自身属性,不包含原型链继承属性
      • 顺序和正常循环遍历对象时返回的顺序一致
      • 类似的方法还有Object.values()Object.entries()
  • 全部属性遍历
    • Object.getOwnPropertyNames(object): string[]:获取对象自身全部属性
      • 仅包含自身属性,不包含原型链继承属性
      • 包括不可枚举属性但不包括Symbol属性
    • Object.getOwnPropertySymbols(object): symbol[]:获取对象自身Symbol属性,与getOwnPropertyNames类似

属性是否可枚举:Object.prototype.propertyIsEnumerable(prop): boolean

var student = {
    name: 'lee',
    [Symbol('skill')]: '绘画',
    [Symbol('skill')]: '演讲'
};

console.log(student.propertyIsEnumerable("name")) // true
console.log(student.propertyIsEnumerable("toString")) // false
console.log(Object.keys(student)) // ["name"]
console.log(Object.getOwnPropertyNames(student)) // ["name"]
console.log(Object.getOwnPropertySymbols(student)) // [Symbol(skill), Symbol(skill)]

删除对象属性

Object 自身没有提供方法删除其自身属性,必须使用delete操作符。delete操作成功后会返回true,否则返回false

const obj = {a: 1};
Object.defineProperty(obj, 'b', {value: 2, writable: false});
console.log(obj); // {a: 1, b: 2}
console.log(delete obj.a); // true
console.log(delete obj.b); // false
console.log(obj); // {b: 2}
console.log(delete obj.a); // true

对象的状态控制

  • Object.preventExtensions(object):阻止对象继续添加属性
  • Object.isExtensible(object):判断对象是否可以添加属性
  • Object.seal(object):锁死对象,无法添加属性,也无法删除属性
  • Object.isSealed(object):判断对象是否锁死
  • Object.freeze(object):冻结对象,无法添加删除属性,也无法修改属性的值,注意:只能实现浅层冻结
  • Object.isFrozen(object):判断对象是否冻结

对象实例方法

  • Object.prototype.valueOf():返回当前对象对应值,主要用途自动类型转换会调用该方法,可以重写覆盖该方法实现自己想要的效果
  • Object.prototype.toString():返回当前对象对应字符串形式,可以自定义toString方法,得到想要的字符串形式
  • Object.prototype.propertyIsEnumerable(attr):判断对象属性是否可枚举
  • Object.prototype.hasOwnProperty(propName: string | symbol): boolean:判断某个属性是否为当前对象自身的属性
  • Object.prototype.isPrototypeOf():判断当前对象是否为另一个对象的原型

Object.is(value1, value2): boolean

判断两个值是否为同一个值

  • ==操作符的区别是不会进行强制类型转换
  • ===操作符的区别是对正负零和NaN的判断逻辑
Object.is(25, 25);                // true
Object.is('foo', 'foo');          // true
Object.is('foo', 'bar');          // false
Object.is(null, null);            // true
Object.is(undefined, undefined);  // true
Object.is(window, window);        // true

Object.is([], []);                // false
var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo);              // true
Object.is(foo, bar);              // false

// Case 2: Signed zero
Object.is(0, -0);                 // false
Object.is(+0, -0);                // false
Object.is(-0, -0);                // true
Object.is(0n, -0n);               // true

// Case 3: NaN
Object.is(NaN, 0 / 0);              // true
Object.is(NaN, Number.NaN)        // true

原型链

  • Object.getPrototypeOf(object):获取对象的原型对象。

results matching ""

    No results matching ""