创建对象两种方式:

  1. let o = new Object();
  2. let b = {}; // 字面量(推荐)

对象构造器可以接受任何类型的参数,并且会自动识别参数类型,选择合适的构造器来完成对象创建:

  1. let o = new Object('something');
  2. o.constructor; // ƒ String() { [native code] }
  3. let n = new Object(123);
  4. n.constructor; // ƒ Number() { [native code] }

Object构造器的成员

Object.prototype

Object的原型对象,是所有对象的原型(包括Object对象本身),JavaScript中其他对象正是通过该属性上添加属性来实现继承关系。

  1. let s = new String('xq');
  2. Object.prototype.custom = 1;
  3. console.log(s.custom); // 1

Object.prototype(原型对象)的成员

Object.prototype.constructor

该属性指向用来构造该对象的构造器,在这里为Object();实例对象constructor指向构造函数。

  1. Object.prototype.constructor === Object; // true
  2. var o = new Object();
  3. o.constructor === Object; // true

Object.prototype.toString(radix)

该方法返回一个用户描述目标对象的字符串,PS,当目标对象是一个Number对象时候,可以传递一个用于进制数的参数radix,该参数默认值为10.

  1. var o = { prop:1 };
  2. o.toString(); // '[object Object]'
  3. var n = new Number(255);
  4. n.toString(); // '255'
  5. n.toString(16); // 'ff'

Object.prototype.toLocaleString()

该方法的作用与toString()基本相同,只不过它做一些本地化处理。该方法会根据当前对象的不同而被重写,例如Date(),Number(),Array(),它们的值都会以本地化的形式输出。当然,对于包括Object()在内的其他大多数对象来说,该方法与toString()是基本相同的。 在浏览器环境下,可以通过BOM对象Navigatorlanguage属性(在IE中则是userLanguage)来了解当前所使用的语言:

  1. navigator.language; //'en-US'

Object.prototype.valueOf()

该方法返回用基本类型所表示指定对象的原始值。如果对象没有原始值,则valueOf将返回对象本身。如果Number对象返回的是它的基本数值,而Date对象返回的是时间戳。如果无法用基本数据类型表示,该方法会放回this本身。

对象 返回值
Array 返回数组对象本身。
Boolean 布尔值。
Date 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC-时间戳。
Function 函数本身。
Number 数字值。
Object 对象本身。这是默认情况。
String 字符串值。
Math 和 Error 对象没有 valueOf 方法。

Object.prototype.hasOwnProperty(prop)

该方法仅在目标属性为对象自身属性时返回true,而当该属性是从原型链中继承而来或根本不存在时,返回false。返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)

  1. const o = { prop:1 };
  2. o.hasOwnProperty('prop'); // true
  3. o.hasOwnProperty('toString'); // false
  4. o.hasOwnProperty('formString'); // false

Object.prototype.isPrototypeOf(obj)

返回布尔值,用于测试一个对象是否存在于另一个对象的原型链上。

  1. const s = new String('');
  2. Object.prototype.isPrototypeOf(s); // true
  3. String.prototype.isPrototypeOf(s); // true
  4. Array.prototype.isPrototypeOf(s); // false

ES5中附加的Object属性

ES5中引入了属性描述符的概念,属性描述符有两种主要形式:数据描述符存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者
数据描述符包括:

  • value:该属性对应的值。可以是任意有效地JavaScript的值,默认undefined
  • writable:当且仅当该属性的writable键值为true时,属性的值,也就是value,才能被赋值运算符修改,默认值为false
  • configurable:当且仅当该属性的configurable键值为true时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认false
  • enumerable:当且仅当该属性的 enumerable键值为 true时,该属性才会出现在对象的枚举属性中。默认false

存取描述符包括:

  • get:属性的 getter函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。默认undefined
  • set:属性的 setter函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this对象。默认undefined。 ```javascript const person = {}; Object.defineProperty(person, ‘legs’, { value: 2, writable: true, configurable: true, enumerable: true });

const person = {}; Object.defineProperty(person, ‘legs’, { set:function(v) { return this.value = v; }, get: function(v) { return this.value; }, configurable: true, enumerable: true });

  1. **数据描述符**(其中属性为:`enumerable``configurable``value``writable`)与**存取描述符**(其中属性为`enumerable``configurable``set()``get()`)之间是有互斥关系的。在定义了`set()``get()`之后,描述符会认为存取操作已被 定义了,其中再定义`value``writable`会**引起错误**。
  2. <a name="object-defineproperty-obj-prop-descriptor-es5"></a>
  3. ### Object.defineProperty(obj, prop, descriptor) (ES5)
  4. 会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
  5. ```javascript
  6. const object1 = {};
  7. Object.defineProperty(object1, 'property1', {
  8. value: 42,
  9. writable: false
  10. });
  11. object1.property1 = 77;
  12. // throws an error in strict mode
  13. console.log(object1.property1);
  14. // expected output: 42

Object.defineProperties(obj, props) (ES5)

该方法的作用与defineProperty()基本相同,只不过它可以用来一次定义多个属性。 比如:

  1. const glass = Object.defineProperties({}, {
  2. 'color': {
  3. value: 'transparent',
  4. writable: true
  5. },
  6. 'fullness': {
  7. value: 'half',
  8. writable: false
  9. }
  10. });
  11. glass.fullness; // 'half'

Object.getPrototypeOf(obj) (ES5)

之前在ES3中,我们往往需要通过Object.prototype.isPrototypeOf()去猜测某个给定的对象的原型是什么,如今在ES5中,我们可以直接询问改对象。你的原型对象(xxx.prototype)是什么?

  1. Object.getPrototypeOf([]) === Array.prototype; // true
  2. Object.getPrototypeOf(Array.prototype) === Object.prototype; // true
  3. Object.getPrototypeOf(Object.prototype) === null; // true

Object.create(obj, descr) (ES5)

该方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
返回值:一个新对象,并为其设置原型对象。带着指定的原型对象和属性。

  1. const parent = { hi: 'Hello' };
  2. const o = Object.create(parent, {
  3. prop: {
  4. value: 1
  5. }
  6. });
  7. o.hi; // 'Hello'
  8. // 获得它的原型
  9. Object.getPrototypeOf(parent) === Object.prototype;
  10. // true 说明parent的原型对象是Object.prototype
  11. Object.getPrototypeOf(o);
  12. // {hi: "Hello"} // 说明o的原型对象是{hi: "Hello"}
  13. o.hasOwnProperty('hi');
  14. // false 说明hi是原型对象上的
  15. o.hasOwnProperty('prop');
  16. // true 说明prop是自身上的属性。

Object.freeze(obj) (ES5)

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

  1. const deadline = Object.freeze({date: 'yesterday'});

Object.keys(obj)

该方法是一种特殊的fot-in循环,只返回当前对象的属性,而这些属性也必须输可枚举的。返回值是一个字符串数组。

  1. const o = { own: 202 };
  2. Object.keys(o); // ['own']

在ES6中附加的Object属性

Object.is(value1, value2)

该方法用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致。 不同之处只有两个:一是+0不等于-0,而是NaN等于自身。

  1. Object.is('xq', 'xq'); // true
  2. Object.is({},{}); // false
  3. Object.is(+0, -0); // false
  4. +0 === -0; // true
  5. Object.is(NaN, NaN); // true
  6. NaN === NaN; // false

Object.assign(target, …sources) (ES6)

该方法用来源对象(source)的所有可枚举的属性复制到目标对象(target)。它至少需要两个对象作为参数,第一个参数是目标对象target,后面的参数都是源对象(source)。只有一个参数不是对象,就会抛出TypeError错误。

  1. const target = { a: 1 };
  2. const source1 = { b: 2 };
  3. const source2 = { c: 3 };
  4. obj = Object.assign(target, source1, source2);
  5. target; // { a:1,b:2,c:3 }
  6. obj; // { a:1,b:2,c:3 }
  7. target === obj; // true
  8. // 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
  9. const source3 = { a:2,b:3,c:4 };
  10. Object.assign(target, source3);
  11. target; // { a:2,b:3,c:4 }