Obejct.assign()
Obejct.create()
Object.defineProperty()
Object.defineProperties()
Object.keys()
Object.values()
Object.entries()
Object.getOwnPropertyNames()
hasOwnProperty()
Object.getPrototypeOf()
Object.is()
Object.freeze()
Object.isFrozen()
Obejct.assign()
描述
Object.assign()
方法用于将自身所以可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
语法
Object.assign(target, ...sources)
案例
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const res = Object.assign({},target,source);
console.log('res',res);//{a: 1, b: 4, c: 5} 返回的新对象是目标对象和多个源对象的覆盖组合对象
//target作为目标对象 虽然返回一个新对象 但target的值也同样会被改变
const resTarget = Object.assign(target,source);
resTarget.d=6;
console.log('resTarget',resTarget);//{a: 1, b: 4, c: 5,d:6}
console.log('target',target); //{a: 1, b: 4, c: 5,d:6}
上面的例子中,因为Object.assign()
返回的是目标对象,resTarget
的目标对象是target
,所以改变了resTarget
,target
也会随之改变,更推荐res
的定义方式,将一个空对象作为目标对象。
如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。
Object.assign
方法只会拷贝源对象自身的并且可枚举的属性到目标对象。该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。如果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用Object.getOwnPropertyDescriptor()
和Object.defineProperty()
。
Object.assign
属于浅拷贝范畴
,因为 Object.assign
拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。
Obejct.create()
描述
Object.create()
使用指定的原型对象和属性创建一个新对象。(创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
。)
语法
Object.create(proto[, propertiesObject])
参数
-
proto 新创建对象的原型对象。
-
propertiesObject
可选。如果没有指定为undefined
,则是要添加到新创建对象的不可枚举(默认)属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()
的第二个参数。如果propertiesObject参数是
null
或非原始包装对象,则抛出一个 TypeError 异常。
案例
利用Object.create()
实现继承
// Shape - 父类(superclass)
function Shape() {
this.x = 0;
this.y = 0;
}
// 父类的方法
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();
console.log('Is rect an instance of Rectangle?',
rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?',
rect instanceof Shape); // true
rect.move(1, 1); // Outputs, 'Shape moved.'
Rectangle.prototype
重定义为Shape.prototype
,然后需要改变原型中constructor
的指向为自己Rectangle
如果你希望能继承到多个对象,则可以使用混入的方式。
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.create 的 propertyObject参数
var o;
// 创建一个原型为null的对象
o = Object.create(null);
// 以字面量方式创建的空对象就相当于:
o = Object.create(Object.prototype);
o = Object.create(Object.prototype, {
// foo会成为所创建对象的数据属性
foo: {
writable: true,
configurable: true,
value: "hello"
},
// bar会成为所创建对象的访问器属性
bar: {
configurable: false,
get: function () { return 10 },
set: function (value) {
console.log("Setting `o.bar` to", value);
}
}
});
function Constructor(){
}
o = new Constructor();
// 上面的一句就相当于:
o = Object.create(Constructor.prototype)
// 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码
console.log('o',o);
Object.defineProperty()
描述
Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性并指定该属性的配置,并返回此对象。
备注:应当直接在
Object
构造器对象上调用此方法,而不是在任意一个Object
类型的实例上调用。
语法
Object.defineProperty(obj, prop, descriptor)
参数
- obj 要定义属性的对象。
- prop 要定义或修改的属性的名称或 Symbol 。
- descriptor 要定义或修改的属性描述符。
详情
该方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,在枚举对象属性时会被枚举到(for...in
或 Object.keys
方法),可以改变这些属性的值,也可以删除这些属性。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty()
添加的属性值是不可修改(immutable
)的。
对象里目前存在的属性描述符有两种主要形式:
- 数据描述符
数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的 - 存取描述符
存取描述符是由 getter 函数和 setter 函数所描述的属性
一个描述符只能是这两者其中之一;不能同时是两者。(因为get和set设置的时候js会忽略value和writable的特性)
这两种描述符都是对象。它们共享以下可选键值(默认值是指在使用 Object.defineProperty() 定义属性时的默认值):
公用
- configurable 默认为 false。
当且仅当该属性的configurable
为true
时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。 - enumerable 默认为 false
当且仅当该属性的enumerable
键值为true
时,该属性才会出现在对象的枚举属性中(是否可枚举 for…in)。
数据描述符
- value 默认为 undefined
该属性对应的值。 - writable 默认为 false
当且仅当该属性的writable
键值为true
时,属性的值,也就是上面的value
,才能被赋值运算符改变。
描述描述符
- get 默认为 undefined
属性的getter
函数,如果没有getter
,则为undefined
。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入this
对象(由于继承关系,这里的this
并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。 - set 默认为 undefined
属性的setter
函数,如果没有setter
,则为undefined
。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的this
对象。
描述符默认值汇总
- 拥有布尔值的键
configurable、enumerable 和 writable
的默认值都是false
。 - 属性值和函数的键
value、get 和 set
字段的默认值为undefined
。
描述符可拥有的键值
如果一个描述符不具有 value、writable、get 和 set
中的任意一个键,那么它将被认为是一个数据描述符。
如果一个描述符同时拥有 value 或 writable 和 get 或 set
键,则会产生一个异常。
记住,这些选项不一定是自身属性,也要考虑继承来的属性。为了确认保留这些默认值,在设置之前,可能要冻结 Object.prototype,明确指定所有的选项,或者通过 Object.create(null) 将 proto 属性指向 null。
案例
如果对象中不存在指定的属性,Object.defineProperty()
会创建这个属性。
数据描述符
var o = {}; // 创建一个新对象
// 在对象中添加一个属性与数据描述符的示例
Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : true
});
console.log(o.a) // 37
存取描述符
var o = {}; // 创建一个新对象
var value;
Object.defineProperty(o, "a", {
enumerable: true,
configurable: true,
get() {
return value
},
set(newvalue) {
console.log('newvalue',newvalue)
value = newvalue;
}
});
console.log(o.a) // undefined
o.a=1; // 触发set特性 打印 newvalue 1
console.log(o.a) // 1
Writable 属性
当 writable
属性设置为 false
时,该属性被称为“不可写的”。它不能被重新赋值。
var o = {}; // 创建一个新对象
Object.defineProperty(o, 'a', {
value: 37,
writable: true // 这就属于显式定义
});
console.log('1',o.a); // 37
o.a = 40;
console.log('2',o.a); // 40 可以修改
Object.defineProperty(o, 'a', {
value: 37,
writable: false
});
o.a = 45;
console.log('3',o.a); // 37 无法修改
Object.defineProperty(o, 'a', {
value: 37,
writable: true
});
o.a = 50;
console.log('4',o.a); // 报错 Uncaught TypeError: Cannot redefine property: a
上面的案例可以看出,writable
配置为true
后属性值可以更改,但设置为false
后就不能更改,并且writable
值也不能再次变为true
;
说明: writable
是单向操作 除了默认值的false
只要是显式的定义了writable
的属性值 如果定义为false
就不能再次定义为true
,否则会报错,初始化可以定义为true
,一但改变成false
就无法再改变!
Enumerable 属性
enumerable
定义了对象的属性是否可以在 for...in
循环和 Object.keys()
中被枚举。
var o = {}; // 创建一个新对象
Object.defineProperty(o, 'a', {
value: 1,
enumerable:true,
configurable:true
});
Object.defineProperty(o, 'b', {
value: 2,
enumerable:true
});
Object.defineProperty(o, 'c', {
value: 3
//默认enumerable为false
});
o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则 enumerable 为 true
for (const key in o) {
console.log('1',key); // a b d
}
Object.defineProperty(o, 'a', {
value: 1,
enumerable:false
});
for (const key in o) {
console.log('2',key); // b d
}
enumerable
跟writable
不一样,只要是配置了configurable:true
,它的值可以任意变为true/false
,没有单向操作的限制。- 如果没有设置
enumerable
,那么默认就是不可以枚举的。 o.d = 4
;没有通过Object.defineProperty
对属性进行配置的,默认enumerable :true
,都是可以枚举的属性。
Configurable 属性
configurable
特性表示对象的属性是否可以被删除,以及除 value
和 writable
特性外的其他特性是否可以被修改。
- 对象的属性是否可以被删除 默认是无法删除
- 除
value
和writable
外其他特性是否可以被修改 (enumerable、get、set
默认都是不能再次进行定义修改的)
对象的属性是否可以被删除
var o = {}; // 创建一个新对象
Object.defineProperty(o, 'a', {
configurable:false,
value:1
});
console.log(o.a); // 1
delete o.a ;
console.log(o.a); // 1
Object.defineProperty(o, 'b', {
configurable:true,
value:1
});
console.log(o.b); // 1
delete o.b ;
console.log(o.b); // undefined
上面的例子中可以得知,只有设置为true的时候才能删除属性
特性是否可以被修改
var o = {}; // 创建一个新对象
Object.defineProperty(o, 'a', {
configurable:true,
get(){
return 1;
}
});
console.log(o.a); // 1
Object.defineProperty(o, 'a', {
configurable:false,
get(){
return 2;
}
});
console.log(o.a); // 报错 Uncaught TypeError: Cannot redefine property: a
Object.defineProperty(o, 'a', {
configurable:true,
get(){
return 3;
}
});
console.log(o.a); // 跟上面报错一样 ,说明 configurable跟 writable属性的特性一样 都是单向操作
configurable
跟writable
属性的特性一样 都是单向操作,除了默认值的false
只要是显式的定义了configurable
的属性值 如果定义为false
就不能再次定义为true
,否则会报错,初始化可以定义为true
,一但改变成false
就无法再改变!configurable
配置为true
后,enumerable
、get
、set
都可以重新定义。
var o = {}; // 创建一个新对象
Object.defineProperty(o, 'a', {
configurable:true,
value:1,
writable:true
});
console.log(o.a); //1
Object.defineProperty(o, 'a', {
value:2,
writable:false
});
o.a = 3;
console.log(o.a); //2
Object.defineProperty(o, 'a', {
get(){
return 3
}
});
console.log(o.a); //3
configurable
为false
的时候,数据描述符和存取描述符之间不能相互转化的,并且存取描述符之间也是不能修改的,true的时候以上说的情况都可以的
所以,更推荐将configurable设置为true,当为false时确实有很大的局限
添加多个属性和默认值
考虑特性被赋予的默认特性值非常重要,通常,使用点运算符和 Object.defineProperty() 为对象的属性赋值时,数据描述符中的属性默认值是不同的,如下例所示。
var o = {};
o.a = 1;
// 等同于:
Object.defineProperty(o, "a", {
value: 1,
writable: true,
configurable: true,
enumerable: true
});
// 另一方面,
Object.defineProperty(o, "a", { value : 1 });
// 等同于:
Object.defineProperty(o, "a", {
value: 1,
writable: false,
configurable: false,
enumerable: false
});
Object.defineProperties()
描述
给对象添加多个属性并分别指定它们的配置。
语法
Object.defineProperties(obj, props)
参数
- obj
在其上定义或修改属性的对象。 - props
要定义其可枚举属性或修改的属性描述符的对象。
案例
var obj = {};
Object.defineProperties(obj, {
'property1': {
value: true,
writable: true
},
'property2': {
value: 'Hello',
writable: false
}
// etc. etc.
});
Object.defineProperties
是Object.defineProperty
的复数形式,Object.defineProperty
对单个属性进行配置,Object.defineProperties
对于多个属性同时进行配置,用法跟Object.defineProperty
一样。
Object.keys()
描述
Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性名组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致。
语法
Object.keys(obj)
参数
- obj 要返回其枚举自身属性的对象。
返回值
一个表示给定对象的所有可枚举属性名的字符串数组。
案例
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']
var o = {
name: 'qfl',
age: 26
}
console.log(Object.keys(o)) // ["name", "age"];
function Fn(){
this.a="a";
this.b='b';
}
Fn.prototype.c = 'c';
var fn = new Fn();
console.log(Object.keys(fn)); // ["a", "b"]
- 对于数组而言,属性名对应的就是索引值
- 只返回自身可枚举的属性,原型上的不会获取 ,如果你想获取一个对象的所有属性,,甚至包括不可枚举的,请查看
Object.getOwnPropertyNames
。
Object.values()
描述
方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for…in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
语法
Object.values(obj)
案例
var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]
var obj1 = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj1)); // ['a', 'b', 'c']
var obj2 = [1, 2, 3, 4];
console.log(Object.values(obj2)); // [1, 2, 3, 4]
Object.entries()
描述
方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for…in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
语法
Object.entries(obj)
参数
obj
可以返回其可枚举属性的键值对的对象。
案例
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
const obj1 = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj1)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
const obj2 = ['a','b','c']
console.log(Object.entries(obj2));[ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
const obj3 = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj3)) {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}
Object.getOwnPropertyNames()
描述
Object.getOwnPropertyNames()
方法返回一个由指定对象的所有自身属性的属性名(不包括原型链上的属性)(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
语法
Object.getOwnPropertyNames(obj)
参数
- obj 一个对象,其自身的可枚举和不可枚举属性的名称被返回。
案例
var arr = ["a", "b", "c"];
console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]
// 类数组对象
var obj = { 0: "a", 1: "b", 2: "c" };
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
//不可枚举属性
var my_obj = Object.create({}, {
getFoo: {
value: function () { return this.foo; },
enumerable: false
}
});
my_obj.foo = 1;
console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
如果你只要获取到可枚举属性,查看Object.keys或用for…in循环(还会获取到原型链上的可枚举属性,不过可以使用hasOwnProperty()方法过滤掉)。
下面的例子演示了该方法不会获取到原型链上的属性:
function ParentClass() {}
ParentClass.prototype.inheritedMethod = function() {};
function ChildClass() {
this.prop = 5;
this.method = function() {};
}
ChildClass.prototype = new ParentClass;
ChildClass.prototype.prototypeMethod = function() {};
console.log(
Object.getOwnPropertyNames(
new ChildClass() // ["prop", "method"]
)
);
hasOwnProperty()
描述
hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键),无法检查原型链上是否具有此属性名。
语法
obj.hasOwnProperty(prop)
参数
- prop 要检测的属性的 String 字符串形式表示的名称,或者 Symbol。
备注
即使属性的值是 null
或 undefined
,只要属性存在,hasOwnProperty
依旧会返回 true。
o = new Object();
o.propOne = null;
o.hasOwnProperty('propOne'); // 返回 true
o.propTwo = undefined;
o.hasOwnProperty('propTwo'); // 返回 true
案例
o = new Object();
o.hasOwnProperty('prop'); // 返回 false
o.prop = 'exists';
o.hasOwnProperty('prop'); // 返回 true
delete o.prop;
o.hasOwnProperty('prop'); // 返回 false
遍历一个对象上的所有属性(自身属性与继承属性)
function Fn(){
this.name='qfl';
this.age=26
}
Fn.prototype.hobby = 'web';
var fn = new Fn();
Object.defineProperty(fn,'name',{
enumerable:false
})
for(var key in fn){
console.log(key);
if(fn.hasOwnProperty(key)){
console.log(`自有属性含有:${key}`); //自有属性含有: age
}else{
console.log(`原型继承属性有:${key}`);//原型继承属性有:hobby
}
for...in
会遍历自身和继承的所有属性,hasOwnProperty
判断是否是自身属性但不包括不可枚举的属性,这样两个都可以区分开来
Object.getPrototypeOf()
描述
Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。
语法
Object.getPrototypeOf(object)
参数
- obj 要返回其原型的对象。
案例
var proto = {};
var obj = Object.create(proto);
console.log( Object.getPrototypeOf(obj) === proto); // true
var reg = /a/;
console.log( Object.getPrototypeOf(reg) === RegExp.prototype); // true
Object.is()
描述
Object.is() 方法判断两个值是否是相同的值。
语法
Object.is(value1, value2);
Object.is() 判断两个值是否相同。如果下列任何一项成立,则两个值相同:
- 两个值都是 undefined
- 两个值都是 null
- 两个值都是 true 或者都是 false
- 两个值是由相同个数的字符按照相同的顺序组成的字符串
- 两个值指向同一个对象
- 两个值都是数字并且
- 都是正零 +0
- 都是负零 -0
- 都是 NaN
- 都是除零和 NaN 外的其它同一个数字
这种相等性判断逻辑和传统的 == 运算不同,== 运算符会对它两边的操作数做隐式类型转换(如果它们类型不同),然后才进行相等性比较,(所以才会有类似 “” == false 等于 true 的现象),但 Object.is 不会做这种类型转换。
案例
Object.is('foo', 'foo'); // true
Object.is(window, window); // true
Object.is('foo', 'bar'); // false
Object.is([], []); // false
var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false
Object.is(null, null); // true
// 特例
Object.is(0, -0); // false
Object.is(0, +0); // true
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true
Object.freeze()
描述
Object.freeze()
方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze()
返回和传入的参数相同的对象。
const obj = {
prop: 42
};
Object.freeze(obj);
obj.prop = 33;
// Throws an error in strict mode
console.log(obj.prop);
// expected output: 42
数据属性的值不可更改(字符串,数字和布尔总是不可变的
),如果一个属性的值是个对象(函数、对象和数组
),则这个对象中的属性是可以修改的,除非它也是个冻结对象。
obj1 = {
internal: {}
};
Object.freeze(obj1);
obj1.internal.a = 'aValue';
obj1.internal.a // 'aValue'
要使对象不可变,需要递归冻结每个类型为对象的属性(深冻结)
// 深冻结函数.
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);
}
obj2 = {
internal: {}
};
deepFreeze(obj2);
obj2.internal.a = 'anotherValue';
obj2.internal.a; // undefined
Object.isFrozen()
描述
Object.isFrozen()
方法判断一个对象是否被冻结。一个对象是冻结的是指它不可扩展,所有属性都是不可配置的,且所有数据属性(即没有getter或setter组件的访问器的属性)都是不可写的。
对应上面Object.freeze()
冻结的方法,如果冻结了 Object.isFrozen
返回为true
,否则返回false
。
总结
Object.assign(target,obj)
- - - 浅拷贝一个对象到目标对象,返回目标对象,将自身所有可枚举的属性都拷贝但不包括原型链上的。Object.create(obj,objProps)
- - - 以目标对象为原型对象创建一个新对象,常用于继承,第二个参数是添加属性对属性进行描述符配置。Object.defineProperty()
- - - 对已有属性或创建一个新属性,对属性进行描述符(数据、存取)配置,返回此对象。Object.defineProperties()
- - - Object.defineProperty()·的复数形式,可以对多个属性同时进行配置。Object.getPrototypeOf()
- - - 返回指定对象的原型,常用于判断对象的原型,Object.getPrototypeOf(obj) === protoObject.is()
- - - 判断两个值是否是相同的值。Object.freeze()
- - - 冻结一个对象,不能更改,数据属性的值不可更改(字符串,数字和布尔总是不可变的),如果一个属性的值是个对象(函数、对象和数组),则这个对象中的属性是可以修改的Object.isFrozen()
- - - 判断一个对象是否被冻结,是否能扩展。
对枚举属性相关的操作方法如下
for... in
- - - 对自有属性和原型链上的所有可枚举的属性都能返回。Object.keys()
- - - 返回所有自身可枚举的属性名(不包括原型链上的)组成的数组。Object.values()
- - - 返回所有自身可枚举的属性值(不包括原型链上的)组成的数组。Object.entries()
- - - 返回所有自身可枚举的属性名和属性值组成的数组组合(不包括原型链上的)组成的数组。[ [‘键’,‘值’],[‘foo’, ‘bar’], [‘baz’, 42] ]Object.getOwnPropertyNames
- - - 返回一个所有可枚举和不可枚举的自身属性的属性名(不包括原型链上的)。xxx.hasOwnProperty(prop)
- - - 判断是否是自有可枚举属性(不包括原型链上的),返回布尔值。
兼容性
下面按照浏览器兼容性分类哪些能使用,哪些不能使用,以ie浏览器为例:
- 不兼容ie:
Object.assign()
、Object.values()
、Object.entries()
、Object.is()
- ie9及以上:
Object.create()
、Object.defineProperty()
、Object.defineProperties()
、Object.getOwnPropertyNames()
、Object.getPrototypeOf()
、Object.isFrozen()
、Object.isFrozen()