Skip to main content

JS 内置对象之 Object

一、属性

1、constructor

所有对象都会从它的原型上继承一个 constructor 属性,constructor 用于返回创建实例对象的 Object 构造函数的引用。

var o = {};
o.constructor === Object; // true

var o = new Object;
o.constructor === Object; // true

var a = [];
a.constructor === Array; // true

var a = new Array;
a.constructor === Array // true

var n = new Number(3);
n.constructor === Number; // true

二、方法

1、assign

Object.assign(target, ...sources)

功能:把一个或多个源对象的可枚举、自有属性值复制到目标对象中,返回值为目标对象。

参数:

  • 目标对象(必须)
  • 至少一个源对象(可选)

返回值:目标对象。

示例:

var target = {
a: 1
};
var source1 = {
b: 2
};
var source2 = {
c: function () {
console.log('c');
}
};
Object.assign(target, source1, source2);

console.log(target); // {a: 1, b: 2, c: ƒ}

拓展:自定义实现一个 assign 方法

// 自定义一个 assign 方法
function copy(target) {
if (target == null) {
throwError('出错:Cannot convert undefined or null to object');
}
var target = new Object(target);
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (source.hasOwnProperty(key)) {
// 若当前属性为源对象自有属性,则拷贝至目标对象
target[key] = source[key];
}
}
}
return target;
}

2、create

Object.create(proto [,propertiesObject])

功能:创建一个对象,其原型为 prototype,同时可添加多个属性。

参数:

  • proto(必须):原型对象,可以为 null 表示没有原型。
  • propertiesObject(可选):包含一个或多个属性描述符的对象。如果该参数被指定且不为 undefined,该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。
propertiesObject 参数详解

数据属性:

  • value:值。
  • writable:是否可修改属性的值。
  • configurable:是否可通过 delete 删除属性,重新定义。
  • enumerable:是否可 for-in 枚举。

访问属性:

  • get():访问。
  • set():设置。

返回值:一个新对象,带着指定的原型对象和属性。

示例:

function Person(name) {
this.name = name;
}
Person.prototype.say = function () {
console.log('my name is ' + this.name + ', my age is ' + this.age);
}

var person = new Person('Tim');
var p = Object.create(person, {
age: {
value: 23,
writable: true,
configurable: true
},
sex: {
configurable: true,
get: function () { return sex + '士'; },
set: function (value) { sex = value; }
}
});

p.sex = '男';
p.say(); // 'my name is Tim, my age is 23'
console.log(p.sex); // '男士'
p.sex = '女';
console.log(p.sex); // '女士'

Object.create(proto [,propertiesObject]) 是 E5 中提出的一种新的对象创建方式,第一个参数是要继承的原型,如果不是一个子函数,可以传一个 null,第二个可选参数是对象的属性描述符。

3、defineProperty

Object.defineProperty(obj, prop, descriptor)

功能:在一个对象上定义一个新属性或修改一个现有属性,并返回该对象。

参数:

  • obj(必须):被操作的目标对象。
  • prop(必须):被定义或修改的目标属性。
  • descriptor(必须):属性的描述符。

返回值:被传递给函数的对象。

示例:

var obj = {};
Object.defineProperty(obj, 'name', {
writable: true,
configurable: true,
enumerable: false,
value: 'Tim'
});

console.log(obj.name); // 'Tim'
for (var key in obj) {
console.log(obj[key]); // 无结果
}

在参数 descriptor 中,如果不指定 configurable, writable, enumerable,则这些属性默认值为 false,如果不指定 value, get, set,则这些属性默认值为 undefined

4、defineProperties

Object.defineProperties(obj, props)

功能:在一个对象上定义一个或多个新属性或修改现有属性,并返回该对象。

参数:

  • obj(必须):被操作的目标对象。
  • props(必须):该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置。

返回值:传递给函数的对象。

示例:

var obj = {};
Object.defineProperties(obj, {
name: {
writable: true,
configurable: true,
enumerable: false,
value: 'Tim'
},
age: {
writable: true,
configurable: true,
enumerable: true,
value: 23
}
});

console.log(obj.name); // 'Tim'
console.log(obj.age); // 23
for (var key in obj) {
console.log(obj[key]); // 23
}

5、seal/isSealed

Object.seal(obj) / Object.isSealed(obj)

功能:密封对象,阻止其修改现有属性的配置特性,即将对象的所有属性的 configurable 特性设置为 false(也就是全部属性都无法重新配置,唯独可以把 writable 的值由 true 改为 false,即冻结属性),并阻止添加新属性,返回该对象。

参数:obj(必须):被密封的对象。

返回值:被密封的对象 / 给定对象是否被密封的 Boolean。

示例:

var obj = { name: 'Tim' };

Object.seal(obj);
console.log(Object.isSealed(obj)); // true

obj.name = 'Bang'; // 修改值成功
console.log(obj.name); // 'Bang'
obj.age = 23; // 无法添加新属性
console.log(obj.age); // undefined

Object.defineProperty(obj, 'name', {
writable: true,
configurable: true,
enumerable: true
}); // 报错:Cannot redefine property: name

补充:Object.isSealed(obj) 用于判断目标对象是否被密封,返回布尔值。

将一个对象密封后仅能保证该对象不被扩展且全部属性不可重配置,但是原属性值却是可以被修改的。

6、freeze/isFrozen

Object.freeze(obj) / Object.isFrozen(obj)

功能:完全冻结对象,在 seal 的基础上,属性值也不可以修改,即每个属性的 wirtable 也被设为 false

参数:obj(必须):被冻结的对象。

返回值:被冻结的对象 / 给定对象是否被冻结的 Boolean。

示例:

var obj = { name: 'Tim' };

Object.freeze(obj);
console.log(Object.isFrozen(obj)); // true

obj.name = 'Bang'; // 修改值失败
console.log(obj.name); // 'Tim'
obj.age = 23; // 无法添加新属性
console.log(obj.age); // undefined

Object.defineProperty(obj, 'name', {
writable: true,
configurable: true,
enumerable: true
}); // 报错:Cannot redefine property: name

补充:Object.isFrozen(obj) 用于判断目标对象是否被冻结,返回布尔值。

7、getOwnPropertyDescriptor

Object.getOwnPropertyDescriptor(obj, prop)

功能:获取目标对象上某自有属性的配置特性(属性描述符),返回值为配置对象。

参数:

  • obj(必须):目标对象。
  • prop(必须):目标自有属性。

返回值:如果指定的属性存在于对象上,则返回其属性描述符对象(property descriptor),否则返回 undefined。

示例:

var obj = {};

Object.defineProperty(obj, 'name', {
writable: true,
configurable: false,
enumerable: true,
value: 'Tim'
});

var prop = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(prop);
// {value: "Tim", writable: true, enumerable: true, configurable: false}

关于描述符:

描述符说明
value属性的值
writable属性的值是否可被改变
enumerable属性的值是否可被枚举
configurable描述符本身是否可被修改,属性是否可被删除
get获取该属性的访问器函数(getter)如果没有访问器,该值为 undefined
set获取该属性的设置器函数(setter)如果没有设置器,该值为 undefined

8、getOwnPropertyDescriptors

Object.getOwnPropertyDescriptors(obj)

功能:获取一个对象的所有自身属性。

参数:obj:目标对象。

返回值:所指定对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。

示例:

var obj = {};

Object.defineProperty(obj, 'name', {
writable: true,
configurable: false,
enumerable: true,
value: 'Tim'
});

var prop = Object.getOwnPropertyDescriptors(obj);
console.log(prop);
// {name: "Tim"}

9、getOwnPropertyNames

Object.getOwnPropertyNames(obj)

功能:获取目标对象上的全部自有属性名(包括不可枚举属性)组成的数组。

参数:obj(必须):目标对象。

返回值:在给定对象上找到的自身属性对应的字符串数组。

示例:

var obj = {};
obj.say = function () { };

Object.defineProperties(obj, {
name: {
writable: true,
configurable: true,
enumerable: true,
value: 'Tim'
},
age: {
writable: true,
configurable: true,
enumerable: false,
value: 23
}
});

var arr = Object.getOwnPropertyNames(obj);
console.log(arr); // ["say", "name", "age"]

10、getPrototypeOf(obj)

Object.getPrototypeOf(object)

功能:获取指定对象的原型,即目标对象的 prototype 属性的值。

参数:obj(必须):目标对象。

返回值:给定对象的原型。如果没有继承属性,则返回 null 。

示例:

function Person(name) {
this.name = name;
}

var person = new Person('Tim');
var p = Object.create(person); // 对象 p 的原型为 person
console.log(p); // Person {}

var __ptoto__ = Object.getPrototypeOf(p);
console.log(__ptoto__); // Person {name: "Tim"}

11、setPrototypeOf

Object.setPrototypeOf(obj, proto)

功能:设置目标对象的原型为另一个对象或 null,返回该目标对象。

参数:

  • obj(必须):目标对象。
  • proto(必须):原型对象。

示例:

var obj = { a: 1 };
var proto = {};
Object.setPrototypeOf(obj, proto); // 设置 obj 对象的原型

proto.b = 2; // 为该原型对象添加属性
proto.c = 3;

console.log(obj.a); // 1
console.log(obj.b); // 2
console.log(obj.c); // 3

上面代码将 proto 对象设为 obj 对象的原型,所以从 obj 对象上可以顺利读取到 proto 对象的属性,也就是原型链上的属性。

Object.setPrototypeOf() 方法的作用与 __proto__ 相同,用来设置当前对象的原型指向的对象(prototype)。它是 ES6 正式推荐的设置原型对象的方法。

12、keys

Object.keys(obj)

功能:获取目标对象上所有可枚举属性组成的数组。

参数:obj(必须):目标对象。

返回值:一个表示给定对象的所有可枚举属性的字符串数组。

示例:

var person = {
type: 'person',
say: function () { }
};

// 以 person 对象为原型,创建 obj 对象
var obj = Object.create(person, {
sex: {
writable: true,
configurable: true,
enumerable: false, // 设置 sex 属性为不可枚举
value: 'male'
},
age: {
writable: true,
configurable: true,
enumerable: true, // 设置 age 属性为可枚举
value: 23
}
});

obj.name = 'Tim'; // 自定义属性 name 默认为可枚举
console.log(obj.propertyIsEnumerable('name'));
// 输出 true,成功验证 name 属性为可枚举

// 用 for-in 可获取 obj 上全部可枚举的属性(包括自有和原型链上的)
var arr = [];
for (var key in obj) {
arr.push(key);
}
console.log(arr); // ["age", "name", "type", "say"]

// 用 Object.keys() 可获取 obj 上全部可枚举的自有属性
console.log(Object.keys(obj)); // ["age", "name"]

Object.keys(obj) 方法获取的集合和 for-in 遍历获取的不同在于,Object.keys() 只获取目标对象上可枚举的自有属性,而 for-in 遍历会包含原型链上可枚举属性一并获取。

Object.keys()Object.getOwnPropertyNames() 的相同之处都是获取目标对象的自有属性,区别在于,后者会连同不可枚举的自有属性也一并获取组成数组并返回。

13、values

Object.values(obj)

功能:返回一个给定对象自身的所有可枚举属性值的数组。

参数:obj(必须):目标对象。

返回值:一个包含对象自身的所有可枚举属性值的数组。

示例:

var obj = {
foo: 'bar',
baz: 42
};
console.log(Object.values(obj)); // ['bar', 42]

var obj = {
0: 'a',
1: 'b',
2: 'c'
};
console.log(Object.values(obj)); // ['a', 'b', 'c']

// 当使用数字键时,会根据键的数字顺序返回的值
var obj = {
100: 'a',
2: 'b',
7: 'c'
};
console.log(Object.values(obj)); // ['b', 'c', 'a']

14、entries

Object.entries(obj)

功能:返回一个给定对象自身可枚举属性的键值对数组。

参数:obj(必须):目标对象。

返回值:给定对象自身可枚举属性的键值对数组。

示例:

const obj = {
foo: 'bar',
baz: 42
};
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

const obj = {
0: 'a',
1: 'b',
2: 'c'
};
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

const obj = {
100: 'a',
2: 'b',
7: 'c'
};
console.log(Object.entries(obj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

15、preventExtensions/isExtensible

Object.preventExtensions(obj) / Object.isExtensible(obj)

功能:使某一对象不可扩展,也就是不能为其添加新属性。

参数:obj(必须):目标对象。

补充:Object.isExtensible(obj) 方法用于判断一个对象是否可扩展,即是否可以添加新属性。

返回值:已经不可扩展的对象 / 给定对象是否可扩展的 Boolean。

示例:

var obj = {
name: 'Tim'
};

Object.preventExtensions(obj); // 阻止 obj 的可扩展性
console.log(Object.isExtensible(obj));
// 输出 false,表明 obj 对象为不可扩展,即阻止成功

obj.age = 23; // 默认添加失败
console.log(obj.age); // undefined