new

作为大家天天使用的操作符,想必大家都不陌生

创建一个对象的通用语法

let obj = new Object();

那么在创建对象的过程中,new 到底做了什么?

MDN

当代码 new Foo(...) 执行时,会发生以下事情:(MDN地址)

  • 一个继承自 Foo.prototype 的新对象被创建。
  • 使用指定的参数调用构造函数 Foo ,并将 this 绑定到新创建的对象。new Foo 等同于 new Foo(),也就是没有指定参数列表,Foo 不带任何参数调用的情况。
  • 由构造函数返回的对象就是 new 表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)

按照这个过程,我们可以大概的模拟一个new的实现

function _new(Super) {//返回一个functionreturn (props)=> {let obj = {}; //创建一个新对象obj.__proto__ = Super.prototype;//继承父类的属性let result = Super.apply(obj,props);//调用Super的构造函数return typeof result === 'object'? result : obj;; //判断Super构造器总返回一个Object}
}var a = _new(Super)(['z'])
a;//{name: "z"}

ECMA-262

再次阅读Ecma262
其过程较MDN多了一些判断,如:

new Object ( [ value ] )
当以一个参数 value 或者无参数调用 Object 构造器,采用如下步骤:

  1. 如果提供了 value, 则
    a.如果 Type(value) 是 Object, 则

      (1)如果 value 是个原生 ECMAScript 对象 , 不创建新对象,简单的返回 value.(2)如果 value 是宿主对象 , 则采取动作和返回依赖实现的结果的方式可以使 依赖于宿主对象的 .

    b.如果 Type(value) 是 String, 返回 ToObject(value).
    c.如果 Type(value) 是 Boolean, 返回 ToObject(value).
    d.如果 Type(value) 是 Number, 返回 ToObject(value).

  2. 断言 : 未提供参数 value 或其类型是 Null 或 Undefined.
  3. 令 obj为一个新创建的原生 ECMAScript 对象 .
  4. 设定 obj 的 [[Prototype]] 内部属性为标准内置的 Object 的 prototype 对象.
  5. 设定 obj 的 [[Class]] 内部属性为 "Object".
  6. 设定 obj 的 [[Extensible]] 内部属性为 true.
  7. 设定 obj 的 8.12 指定的所有内部方法
  8. 返回 obj.

重新来修改下我们的模拟

function _new(Super) {//返回一个functionreturn (value) => {if (value) {switch (typeof value) {case 'object'://这里因为不同的宿主环境也就是不同的引擎会有不同的写法,找了很多博文书籍也没有详解具体的判断逻辑或方法,只好先写伪代码了if (宿主对象) {//采取动作和返回依赖实现的结果的方式可以使依赖于宿主对象的} else {return value}break;case 'string':return new String(value);break;case 'boolean':return new Boolean(value);break;case 'number':return new Number(value);break;default:break;}}let obj = {}; //创建一个新对象obj.__proto__ = Super.prototype; //继承父类的属性//修改内部属性class 为 “Object”,不过ecma262没有提供任何方法去修改,只提供了一种访问方法 Object.prototype.toString.call("我们的对象")//修改内部属性Extensible为 true,不过目前没有提供方法去修改,只有一个修改为false Object.preventExtensions("我们的对象");let result = Super.apply(obj, value); //调用Super的构造函数return typeof result === 'object' ? result : obj;; //判断Super构造器总返回一个Object}
}var a = _new(Super)(['z'])
a; //{name: "z"}

欢迎补充

(详解)你应该知道的new操作符相关推荐

  1. Git详解之必知点----Git、本地仓库、远程仓库、IDEA集成Git

    Git详解之必知点 1.Git介绍 1.1版本控制(理解) 1.2开发中存在的问题(理解) 1.3SVN版本控制(理解) 1.4Git版本控制(理解) 2.Git下载和安装 2.1Git的安装(应用) ...

  2. C语言最全操作符详解,一文精通所有操作符!

    文章目录 前言 一.除号"/" 二."%"除法取余数 三.左移操作符"<<"和右移操作符">>" ...

  3. Web3 哪个赛道最有机会?带你详解Web3基础设施赛道的“超级项目”

    一文能不能看懂Web3?绝对不可能!Web3已是技术.应用.理念等"多纬内涵"叠加的超级生态系统.随便罗列一些概念,你熟悉几个? Web3的操作系统:公链.Layer2: Web3 ...

  4. C语言操作符详解------移位操作符

    今天给大家带来的是移位操作符的详解 首先大家在学习移位操作符之前要明确:移位操作符移动的是二进制位!!! <<   左移操作符 >>   右移操作符 注意:移位操作符的操作数只 ...

  5. tgp饥荒 服务器无响应,饥荒TGP版常见运行问题有哪些_TGP版礼包领取及邀请添加好友方法详解_快吧单机游戏...

    <饥荒>TGP版常见运行问题有哪些呢,玩家们是不是很想知道呢?下面小编为玩家们带来了<饥荒>TGP版礼包领取及邀请添加好友方法详解,还不知道的玩家快来看看吧. 1.皮肤礼包如何 ...

  6. SLAM学习笔记(二十)LIO-SAM流程及代码详解(最全)

    写在前面 关于安装配置,博客LIO_SAM实测运行,论文学习及代码注释[附对应google driver数据] 我觉得已经写的比较完善了.但是我觉得在注释方面,这位博主写的还不够完善,因此在学习以后, ...

  7. GET 和 POST详解

    GET 和 POST详解 转载: 知乎:https://www.zhihu.com/question/28586791 一.HTTP请求方法 Http协议定义了很多与服务器交互的方法,最基本的有4种, ...

  8. 图文详解Modbus-RTU协议(转载)

    图文详解Modbus-RTU协议 - 知乎 (zhihu.com) Modbus RTU(Remote Terminal Unit 远程终端单元):这种方式常采用RS-485做为物理层,一般利用芯片的 ...

  9. UNet论文详解分析

    论文地址:https://arxiv.org/abs/1505.04597 一.概要 2015年UNet的出现使得原先需要数千个带注释的数据才能进行训练的深度学习神经网络大大减少了训练所需要的数据量, ...

最新文章

  1. Java入门系列-16-继承
  2. 关于Linux vi命令 vi命令一览表
  3. pytorch 之手写数字生成网络
  4. 【翻译自mos文章】怎么正确的计算一个ip地址的subnet id?
  5. 在64位linux下编译32位程序
  6. 新手怎么读懂一个中型的Django项目
  7. USTC English Club Note20211223
  8. GDCM:gdcm::Object的测试程序
  9. 2018年9月份GitHub上最热门的Python项目
  10. php中html富文本编辑器,php + wangEditor 富文本编辑器的配置
  11. 属于web框架的python库_(2017)我不建议使用的Python Web框架
  12. NTFS文件系统的简述
  13. 《项目百态:软件项目管理面面观》三模式总结
  14. html5代码书写规范
  15. alsa driver--card
  16. 2021年山东省安全员C证报名考试及山东省安全员C证操作证考试
  17. WTL 自绘控件库 (CQsRadioBox)
  18. 实战案例分享:我用 Python 预测房价走势
  19. 深度神经网络简单介绍,神经网络设计与实现
  20. php写字本写,php在图片上写字的类

热门文章

  1. 爆牙齿的世界杯日记(小组末轮AB组)
  2. numpy 排序, 查询功能
  3. iOS 之 const
  4. IOS学习之数据库(6)--SQLite常用的函数
  5. hibernate session的load和get方法
  6. WPF中引入外部资源
  7. Windows Azure NotificationHub+Firebase Cloud Message 实现消息推动(付源码)
  8. Flask部署| gunicorn、nginx部署flask项目,并用supervisor来管理进程
  9. java反射使用及性能比较
  10. mysql默认安装目录说明