静态方法
遍历
Object.keys()
Object.keys() 方法用来遍历对象的属性,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']
Object.values()
Object.values()方法用来遍历对象的属性,值的顺序与使用for…in循环的顺序相同
var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]
Object.entries()
Object.entries()方法用来遍历键值,顺序与使用for…in循环的顺序相同
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
//将Object转换为Map
var obj = { foo: "bar", baz: 42 };
var map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }
对象属性
Object.getOwnxxx
- Object.getOwnPropertyNames(obj)方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
- Object.getOwnPropertyDescriptor(obj, prop)方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
- Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符。
- Object.getOwnPropertySymbols(obj) 方法返回一个给定对象自身的所有 Symbol 属性的数组
var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
// d {
// configurable: true,
// enumerable: true,
// value: 42,
// writable: true
// }
var obj = {};
var a = Symbol("a");
obj[a] = "localSymbol";
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols) // [Symbol(a)]
Object.defineProperty()/Object.defineProperties()
Object.defineProperty()方法允许通过属性描述对象,定义或修改一个属性,然后返回修改后的对象,它的用法如下。
Object.defineProperty方法接受三个参数,依次如下。
- object:属性所在的对象
- propertyName:字符串,表示属性名
- attributesObject:属性描述对象
如果一次性定义或修改多个属性,可以使用Object.defineProperties()方法var obj = Object.defineProperty({}, 'p', {
value: 123,
writable: false,
enumerable: true,
configurable: false,
get() { return ...; }, //可选
set(value) { ... = value; }, //可选
});
控制对象
Object.preventExtensions()
Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。
Object.isExtensible() 方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)
Object.seal()
**Object.seal()**
可以使一个对象无法添加新属性的同时,也无法删除旧属性,还是可以改属性值的
其本质是通过修改属性的 configurable 为 false 来实现的,不能defineProperty
Object.isSealed() 方法判断一个对象是否被密封。
Object.freeze()
Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。使得这个对象实际上变成了常量。
Object.isFrozen()方法判断一个对象是否被冻结。
// 深冻结函数.
function deepFreeze(obj) {
// 取回定义在obj上的属性名
var propNames = Object.getOwnPropertyNames(obj);
// 在冻结自身之前冻结属性
propNames.forEach(function(name) {
var prop = obj[name];
// 如果prop是个对象,冻结它
if (typeof prop == 'object' && prop !== null)
deepFreeze(prop);
});
// 冻结自身(no-op if already frozen)
return Object.freeze(obj);
}
原型
Object.create()
该方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
语法:Object.create(proto,[propertiesObject])
- proto 新创建对象的原型对象。
- propertiesObject可选。需要传入一个对象,该对象的属性类型参照Object.defineProperties()的第二个参数。
使用: ```javascript // Shape - 父类(superclass) function Shape() { this.x = 0; this.y = 0; }//模拟实现
function createObject(proto) {
function F(){}
F.prototype = proto;
return new F();
}
// 父类的方法 Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info(‘Shape moved.’); };
// Rectangle - 子类(subclass) function Rectangle() { Shape.call(this); // call super constructor. }
// 子类继承父类 Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle();
rect instanceof Rectangle); // true
rect instanceof Shape); // true rect.move(1, 1); // Outputs, ‘Shape moved.’
**实现多继承**
```javascript
function MyClass() {
SuperClass.call(this);
OtherSuperClass.call(this);
}
// 继承一个类
MyClass.prototype = Object.create(SuperClass.prototype);
// 混合其它
Object.assign(MyClass.prototype, OtherSuperClass.prototype);
// 重新指定constructor
MyClass.prototype.constructor = MyClass;
MyClass.prototype.myMethod = function() {
// do a thing
};
object.assign 会把 OtherSuperClass原型上的函数拷贝到 MyClass原型上,
使 MyClass 的所有实例都可用 OtherSuperClass 的方法
Object.assign()
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。
语法:Object.assign(target, …sources)
- target:目标对象
- source:源对象
如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。
const o1 = { a: 1, b: 1, c: 1 };
const o2 = { b: 2, c: 2 };
const o3 = { c: 3 };
const obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
Object.setPrototypeOf()
Object.setPrototypeOf() 方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或 null。
语法:Object.setPrototypeOf(obj, prototype)
- obj:要设置其原型的对象
- prototype:该对象的原型
等于
function (obj, proto) {
obj.__proto__ = proto;
return obj;
}
Object.getPrototypeOf()
Object.getPrototypeOf() 方法返回指定对象的原型(标准方法)(内部[[Prototype]]属性的值)。
等于 __proto__
(非标准方法)
var proto = {};
var obj = Object.create(proto);
Object.getPrototypeOf(obj) === proto; // true
实例方法
isPrototypeOf()
用于测试一个对象是否存在于另一个对象的原型链上。
function Foo() {}
function Bar() {}
function Baz() {}
Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);
var baz = new Baz();
console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true
//检查 baz 对象是否继承自 Foo.prototype:
if (Foo.prototype.isPrototypeOf(baz)) {
// do something safe
}
hasOwnProperty()
Object.prototype.hasOwnProperty()方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。
const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// true
toString()
toString方法的作用是返回一个对象的字符串形式,默认情况下返回类型字符串。
不同数据类型的Object.prototype.toString方法返回值如下。
- 数值:返回[object Number]。
- 字符串:返回[object String]。
- 布尔值:返回[object Boolean]。
- undefined:返回[object Undefined]。
- null:返回[object Null]。
- 数组:返回[object Array]。
- arguments 对象:返回[object Arguments]。
- 函数:返回[object Function]。
- Error 对象:返回[object Error]。
- Date 对象:返回[object Date]。
- RegExp 对象:返回[object RegExp]。
- 其他对象:返回[object Object]。
可以用它判断类型
// 判断数据类型函数
function toRawType (value) {
return Object.prototype.toString.call(value).slice(8, -1)
}
//结果
toRawType({}) // Object
toRawType([]) // Array
toRawType(true) // Boolean
toRawType(undefined) // Undefined
toRawType(null) // Null
toRawType(function(){}) // Function
propertyIsEnumerable()
实例对象的propertyIsEnumerable()
方法返回一个布尔值,用来判断某个属性是否可遍历。注意,这个方法只能用于判断对象自身的属性,对于继承的属性一律返回false。
var obj = {};
obj.p = 123;
obj.propertyIsEnumerable('p') // true
obj.propertyIsEnumerable('toString') // false
包装对象
所谓“包装对象”,指的是与数值、字符串、布尔值分别相对应的Number、String、Boolean三个原生对象。这三个原生对象可以把原始类型的值变成(包装成)对象。
这三个对象作为构造函数使用(带有new)时,可以将原始类型的值转为对象;
作为普通函数使用时(不带有new),可以将任意类型的值,转为原始类型的值。
var v1 = new Number(123);
var v2 = new String('abc');
var v3 = new Boolean(true);
typeof v1 // "object"
typeof v2 // "object"
typeof v3 // "object"
// 字符串转为数值
Number('123') // 123
// 数值转为字符串
String(123) // "123"
// 数值转为布尔值
Boolean(123) // true
valueOf()
valueOf()方法返回包装对象实例对应的原始类型的值
new Number(123).valueOf() // 123
new String('abc').valueOf() // "abc"
new Boolean(true).valueOf() // true
toString()
toString()方法返回对应的字符串形式。
new Number(123).toString() // "123"
new String('abc').toString() // "abc"
new Boolean(true).toString() // "true"
自动转换
调用包装对象的属性和方法时,原始类型的值会自动当作包装对象调用。
'abc'.length // 3
// 自动转换生成的包装对象是只读的,无法修改。所以,字符串无法添加新属性
调用结束后,包装对象实例会自动销毁。这意味着,下一次调用字符串的属性时,实际是调用一个新生成的对象,而不是上一次调用时生成的那个对象,所以取不到赋值在上一个对象的属性。
如果要为字符串添加属性,只有在它的原型对象