创建对象两种方式:
let o = new Object();let b = {}; // 字面量(推荐)
对象构造器可以接受任何类型的参数,并且会自动识别参数类型,选择合适的构造器来完成对象创建:
let o = new Object('something');o.constructor; // ƒ String() { [native code] }let n = new Object(123);n.constructor; // ƒ Number() { [native code] }
Object构造器的成员
Object.prototype
Object的原型对象,是所有对象的原型(包括Object对象本身),JavaScript中其他对象正是通过该属性上添加属性来实现继承关系。
let s = new String('xq');Object.prototype.custom = 1;console.log(s.custom); // 1
Object.prototype(原型对象)的成员
Object.prototype.constructor
该属性指向用来构造该对象的构造器,在这里为Object();实例对象constructor指向构造函数。
Object.prototype.constructor === Object; // truevar o = new Object();o.constructor === Object; // true
Object.prototype.toString(radix)
该方法返回一个用户描述目标对象的字符串,PS,当目标对象是一个Number对象时候,可以传递一个用于进制数的参数radix,该参数默认值为10.
var o = { prop:1 };o.toString(); // '[object Object]'var n = new Number(255);n.toString(); // '255'n.toString(16); // 'ff'
Object.prototype.toLocaleString()
该方法的作用与toString()基本相同,只不过它做一些本地化处理。该方法会根据当前对象的不同而被重写,例如Date(),Number(),Array(),它们的值都会以本地化的形式输出。当然,对于包括Object()在内的其他大多数对象来说,该方法与toString()是基本相同的。 在浏览器环境下,可以通过BOM对象Navigator的language属性(在IE中则是userLanguage)来了解当前所使用的语言:
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。返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)
const o = { prop:1 };o.hasOwnProperty('prop'); // trueo.hasOwnProperty('toString'); // falseo.hasOwnProperty('formString'); // false
Object.prototype.isPrototypeOf(obj)
返回布尔值,用于测试一个对象是否存在于另一个对象的原型链上。
const s = new String('');Object.prototype.isPrototypeOf(s); // trueString.prototype.isPrototypeOf(s); // trueArray.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 });
**数据描述符**(其中属性为:`enumerable`,`configurable`,`value`,`writable`)与**存取描述符**(其中属性为`enumerable`,`configurable`,`set()`,`get()`)之间是有互斥关系的。在定义了`set()`和`get()`之后,描述符会认为存取操作已被 定义了,其中再定义`value`和`writable`会**引起错误**。<a name="object-defineproperty-obj-prop-descriptor-es5"></a>### Object.defineProperty(obj, prop, descriptor) (ES5)会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。```javascriptconst object1 = {};Object.defineProperty(object1, 'property1', {value: 42,writable: false});object1.property1 = 77;// throws an error in strict modeconsole.log(object1.property1);// expected output: 42
Object.defineProperties(obj, props) (ES5)
该方法的作用与defineProperty()基本相同,只不过它可以用来一次定义多个属性。 比如:
const glass = Object.defineProperties({}, {'color': {value: 'transparent',writable: true},'fullness': {value: 'half',writable: false}});glass.fullness; // 'half'
Object.getPrototypeOf(obj) (ES5)
之前在ES3中,我们往往需要通过Object.prototype.isPrototypeOf()去猜测某个给定的对象的原型是什么,如今在ES5中,我们可以直接询问改对象。你的原型对象(xxx.prototype)是什么?
Object.getPrototypeOf([]) === Array.prototype; // trueObject.getPrototypeOf(Array.prototype) === Object.prototype; // trueObject.getPrototypeOf(Object.prototype) === null; // true
Object.create(obj, descr) (ES5)
该方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。
返回值:一个新对象,并为其设置原型对象。带着指定的原型对象和属性。
const parent = { hi: 'Hello' };const o = Object.create(parent, {prop: {value: 1}});o.hi; // 'Hello'// 获得它的原型Object.getPrototypeOf(parent) === Object.prototype;// true 说明parent的原型对象是Object.prototypeObject.getPrototypeOf(o);// {hi: "Hello"} // 说明o的原型对象是{hi: "Hello"}o.hasOwnProperty('hi');// false 说明hi是原型对象上的o.hasOwnProperty('prop');// true 说明prop是自身上的属性。
Object.freeze(obj) (ES5)
Object.freeze() 方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。
const deadline = Object.freeze({date: 'yesterday'});
Object.keys(obj)
该方法是一种特殊的fot-in循环,只返回当前对象的属性,而这些属性也必须输可枚举的。返回值是一个字符串数组。
const o = { own: 202 };Object.keys(o); // ['own']
在ES6中附加的Object属性
Object.is(value1, value2)
该方法用来比较两个值是否严格相等。它与严格比较运算符(===)的行为基本一致。 不同之处只有两个:一是+0不等于-0,而是NaN等于自身。
Object.is('xq', 'xq'); // trueObject.is({},{}); // falseObject.is(+0, -0); // false+0 === -0; // trueObject.is(NaN, NaN); // trueNaN === NaN; // false
Object.assign(target, …sources) (ES6)
该方法用来源对象(source)的所有可枚举的属性复制到目标对象(target)。它至少需要两个对象作为参数,第一个参数是目标对象target,后面的参数都是源对象(source)。只有一个参数不是对象,就会抛出TypeError错误。
const target = { a: 1 };const source1 = { b: 2 };const source2 = { c: 3 };obj = Object.assign(target, source1, source2);target; // { a:1,b:2,c:3 }obj; // { a:1,b:2,c:3 }target === obj; // true// 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。const source3 = { a:2,b:3,c:4 };Object.assign(target, source3);target; // { a:2,b:3,c:4 }
