1、创建对象的方式不同
- new Object()
:通过构造函数来创建对象, 添加的属性是在自身实例下。
- Object.create()
:es6
创建对象的另一种方式,可以理解为继承一个对象, 添加的属性是在原型下。
// new Object() 方式创建
var a = { rep : 'apple' }
var b = new Object(a)
console.log(b) // {rep: "apple"}
console.log(b.__proto__) // {}
console.log(b.rep) // {rep: "apple"}
// Object.create() 方式创建
var a = { rep: 'apple' }
var b = Object.create(a)
console.log(b) // {}
console.log(b.__proto__) // {rep: "apple"}
console.log(b.rep) // {rep: "apple"}
Object.create()方法创建的对象时,属性是在原型下面的,也可以直接访问 b.rep // {rep: "apple"} ,
此时这个值不是b自身的,是它通过原型链proto来访问到b的值。
2、创建对象属性的性质不同
// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
o = Object.create({}, { p: { value: 42 } })
// 省略了的属性特性默认为false,所以属性p是不可写,不可枚举,不可配置的:
o.p = 24
o.p
//42
o.q = 12
for (var prop in o) {
console.log(prop)
}
//"q"
delete o.p
//false
Object.create() 用第二个参数来创建非空对象的属性描述符默认是为false的,而构造函数或字面量方法创建的对象属性的描述符默认为true。看下图解析:
3、创建空对象时不同
字面量new出来的对象和 Object.create(null)创建出来的对象有什么区别
答:
字面量和new创建出来的对象会继承Object的方法和属性,他们的隐式原型会指向Object的显式原型,
而 Object.create(null)创建出来的对象原型为null,作为原型链的顶端,自然也没有继承Object的方法和属性
- 语法:
Object.create(proto, [propertiesObject])
方法创建一个新对象,使用现有的对象来提供新创建的对象的proto。- __proto__属性
JavaScript 的对象继承是通过原型链实现的。ES6 提供了更多原型对象的操作方法。 - __proto__属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。目前只有浏览器环境必须部署有这个属性,其他运行环境不一定要部署,因此不建议使用这个属性,而是使用下面这些来
Object.setPrototypeOf()
(写操作)、Object.getPrototypeOf()
(读操作)、Object.create()(生成操作)
代替。
- __proto__属性
Object.create()
描述:该方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
;
格式:Object.create(proto[, propertiesObject])
用法:如果用传统的方法要给一个对象的原型上添加属性和方法,是通过__propt__
实现的
var proto = {
y: 20,
z: 40,
showNum(){}
};
var o = Object.create(proto);
如果是不用Object,create()方法,我们是如何给对象原型添加属性和方法的?
------ 通过构造函数或者类,例如:
//创建一个构造函数或者类
var People = function(){}
People.prototype.y = 20
People.prototype.showNum = function() {}
//通过构造函数创建实例
var p = new People();
console.log(p.__proto__ === People.prototype) // true
现在有 Object.create() 就简单的多了
Object.setPrototypeOf
描述:该方法的作用与__proto__
相同,用来设置一个对象的 prototype 对象,返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。
格式:Object.setPrototypeOf(object, prototype)
用法:
var proto = {
y: 20,
z: 40
};
var o = { x: 10 };
Object.setPrototypeOf(o, proto);
输出结果中看出,添加的方法是在原型上的。就类似于
obj.__proto__ = proto;
Object.getPrototypeOf()
描述:用于读取一个对象的原型对象;
格式:Object.getPrototypeOf(obj);
用法:
Object.getPrototypeOf('foo') === String.prototype // true
Object.getPrototypeOf(true) === Boolean.prototype // true
参考资料: