Object.create() 和 new Object(), {} 创建对象的区别 & new 操作运算符实现原理

在 JavaScript 中,Object.create() 和 new Object(), {} 都用于创建对象,但它们有以下区别:

原型设置:

  1. Object.create() 可以明确指定创建对象的原型对象。
  2. new Object(), {} 创建的对象的原型是 Object.prototype。

属性继承:

  1. 使用 Object.create() 时,如果指定的原型对象具有属性和方法,新创建的对象可以继承这些属性和方法。
  2. new Object(), {} 创建的对象仅继承 Object.prototype 上的默认属性和方法。

灵活性:

  1. Object.create() 提供了更灵活的方式来控制对象的原型链结构,允许创建具有特定原型的空对象或继承部分属性和方法。
  2. 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);

运行结果:

相关推荐
哆啦A梦158820 小时前
搜索页面布局
前端·vue.js·node.js
_院长大人_21 小时前
el-table-column show-overflow-tooltip 只能显示纯文本,无法渲染 <p> 标签
前端·javascript·vue.js
SevgiliD21 小时前
el-table中控制单列内容多行超出省略及tooltip
javascript·vue.js·elementui
要加油哦~21 小时前
JS | 知识点总结 - 原型链
开发语言·javascript·原型模式
哆啦A梦15881 天前
axios 的二次封装
前端·vue.js·node.js
阿珊和她的猫1 天前
深入理解与手写发布订阅模式
开发语言·前端·javascript·vue.js·ecmascript·状态模式
yinuo1 天前
一行 CSS 就能搞定!用 writing-mode 轻松实现文字竖排
前端
snow@li1 天前
html5:拖放 / demo / 拖放事件(Drag Events)/ DataTransfer 对象方法
前端·html·拖放
爱看书的小沐1 天前
【小沐杂货铺】基于Three.js渲染三维风力发电机(WebGL、vue、react、WindTurbine)
javascript·vue.js·webgl·three.js·opengl·风力发电机·windturbine
qq_398586541 天前
Threejs入门学习笔记
javascript·笔记·学习