在 JavaScript 中,Object.create() 和 new Object(), {} 都用于创建对象,但它们有以下区别:
原型设置:
- Object.create() 可以明确指定创建对象的原型对象。
- new Object(), {} 创建的对象的原型是 Object.prototype。
属性继承:
- 使用 Object.create() 时,如果指定的原型对象具有属性和方法,新创建的对象可以继承这些属性和方法。
- new Object(), {} 创建的对象仅继承 Object.prototype 上的默认属性和方法。
灵活性:
- Object.create() 提供了更灵活的方式来控制对象的原型链结构,允许创建具有特定原型的空对象或继承部分属性和方法。
- new Object(), {} 是一种更简单直接的创建普通对象的方式。
代码示例:
js
const obj_null = Object.create(null)
console.log('obj_null', obj_null, obj_null.__proto__);
const new_obj = new Object()
console.log('new_obj', new_obj, new_obj.__proto__);
const normal_obj= {}
console.log('normal_obj', normal_obj, normal_obj.__proto__);
运行结果:
Object.create() 实现原理
js
function myObjectCreate(proto, properties) {
function Constructor() {}
Constructor.prototype = proto;
const obj = new Constructor();
if (properties) {
for (let key in properties) {
if (properties.hasOwnProperty(key)) {
Object.defineProperty(obj, key, properties[key]);
}
}
}
return obj
}
实现原理验证:
js
let proto = { x: 10 };
let myCreateObj = myObjectCreate(proto, {
childName: { value: 'my_create_obj', enumerable: false },
childAge: { value: 20, enumerable: true },
});
console.log('myCreateObj', myCreateObj.__proto__)
const obj = {
name: 'parentObj',
age: 40
}
const createObj = Object.create(obj, {
childName: { value: 'create_obj', enumerable: false },
childAge: { value: 20, enumerable: true },
});
console.log('createObj', createObj.__proto__)
运行结果:
补充:扩展运算符(...) 和 Object.assign() 属于浅拷贝
且只继承父元素可枚举
的属性, eg:
js
const obj_1 = { ...createObj}
const obj_2 = Object.assign({}, createObj)
console.log('obj_1:', obj_1);
console.log('obj_2:', obj_2);
运行结果:
new 操作运算符实现原理
js
function my_new(fn, ...args) {
const obj = {}
obj.__proto__ = fn.prototype
const res = fn.apply(obj, args)
return typeof res === 'object' && res !== null ? res : obj
}
// 定义一个构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
// 使用自定义的 myNew 模拟 new 操作符创建对象
let person = my_new(Person, 'John', 30);
console.log(person);
运行结果: