手写实现JS中的new


Posted in Javascript onNovember 07, 2021

⚠ 预备知识:

  • 了解原型和原型链
  • 了解this绑定

1 new 运算符简介

MDN文档:new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

class Person {
    constructor(name) {
        this.name = name;
    }
}
// 创建自定义对象类型的实例
const person = new Person('小明')
// 创建具有构造函数的内置对象的实例
const date = new Date()

new的作用:创建对象的实例

2 new 究竟干了什么事

上面说了new的作用是创建对象的实例,那么它究竟是怎么创建实例的,内部干了哪几件事?

以new Person()为例,当它执行时,会发生以下事情:

创建一个空的简单JS对象

const obj = {}

给这个对象添加属性__proto__,并将该属性链接到构造函数的原型对象

obj.__proto__ = Person.prototype

调用构造函数Person,并将this绑定到新创建的对象obj

Person.apply(obj)

如果构造函数没有显式返回一个对象,则返回新创建的对象,即obj

3 模拟实现 new 运算符

如上所述,new运算符就干了这么4件事,下面我们就根据这4个步骤用函数来模拟实现new(面试手写代码)

const _new = function(constructor, ...args) {
    const obj = {}
    obj.__proto__ = constructor.prototype
    const res = constructor.apply(obj, args)
    // 这一步在"补充"中会详细解释
    return res instanceof Object ? res : obj
}

代码非常简单,就是按照上面4步,一步一步写就可以了

4 补充

ES5提供了Object.create方法,该方法可以创建一个对象,并让新对象的__proto__属性指向已经存在的对象。

所以我们可以使用这个方法合并1、2两步

const obj = Object.create(constructor.prototype)
// 等价于
const obj = {}
obj.__proto__ = constructor.prototype

对于第4步,再解释一下

  • 如果构造函数没有显式return(通常情况)那么person就是新创建的对象obj
  • 如果构造函数返回的不是一个对象,比如1、"abc" 那么person还是新创建的对象obj
function Person() {
    ...
   return 1
}

如果构造函数显式返回了一个对象,比如{}function() {}

那么person就不是新创建的对象obj了,而是显式return的这个对象

function Person() {
  // 函数也是对象
  return function() {}
}

所以我们在_new函数最后一句代码是:

return res instanceof Object ? res : obj

注意:模拟实现的函数_new传入的参数只能是构造函数,不能是类

class Animal {  ...}_new(Animal)// 会报错:Class constructor Animal cannot be invoked without 'new'// 类只能通过new来创建

到此这篇关于手写实现JS中的new的文章就介绍到这了,更多相关JS中的new内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
不要小看注释掉的JS 引起的安全问题
Dec 27 Javascript
jquery下实现overlay遮罩层代码
Aug 25 Javascript
jQuery焦点图轮播特效代码分享(3款)
Sep 05 Javascript
使用基于Node.js的构建工具Grunt来发布ASP.NET MVC项目
Feb 15 Javascript
Javascript类型转换的规则实例解析
Feb 23 Javascript
深入理解JS中的substr和substring
Apr 26 Javascript
15个值得开发人员关注的jQuery开发技巧和心得总结【经典收藏】
May 25 Javascript
AngularJS 工作原理详解
Aug 18 Javascript
Vue开发中遇到的跨域问题及解决方法
Feb 11 Javascript
Vue 如何使用props、emit实现自定义双向绑定的实现
Jun 05 Javascript
vue实现用户长时间不操作自动退出登录功能的实现代码
Jul 23 Javascript
使用Vue实现一个树组件的示例
Nov 06 Javascript
用JS写一个发布订阅模式
Nov 07 #Javascript
浅谈JavaScript浅拷贝和深拷贝
JavaScript严格模式不支持八进制的问题讲解
Javascript使用integrity属性进行安全验证
Nov 07 #Javascript
JavaScript中时间格式化新思路toLocaleString()
Nov 07 #Javascript
JavaScript中isPrototypeOf函数
JavaScript原型链详解
You might like
Smarty+QUICKFORM小小演示
2007/02/25 PHP
PHP 中检查或过滤IP地址的实现代码
2011/11/27 PHP
Opcache导致php-fpm崩溃nginx返回502
2015/03/02 PHP
php实现数据库的增删改查
2017/02/26 PHP
laravel自定义分页的实现案例offset()和limit()
2019/10/15 PHP
浅析PHP反序列化中过滤函数使用不当导致的对象注入问题
2020/02/15 PHP
Jquery插件之打造自定义的select标签
2011/11/30 Javascript
动态的改变IFrame的高度实现IFrame自动伸展适应高度
2012/12/28 Javascript
解析使用JS 清空File控件的路径值
2013/07/08 Javascript
css配合jquery美化 select
2013/11/29 Javascript
全屏js头像上传插件源码高清版
2016/03/29 Javascript
javascript 常用验证函数总结
2016/06/28 Javascript
AngularJS指令详解及示例代码
2016/08/16 Javascript
js原生Ajax的封装和原理详解
2017/03/11 Javascript
bootstrap3-dialog-master模态框使用详解
2017/08/22 Javascript
仿京东快报向上滚动的实例
2017/12/13 Javascript
Vue中的情侣属性$dispatch和$broadcast详解
2019/03/07 Javascript
2019年度web前端面试题总结(主要为Vue面试题)
2020/01/12 Javascript
基于Vue3.0开发轻量级手机端弹框组件V3Popup的场景分析
2020/12/30 Vue.js
详解python的几种标准输出重定向方式
2016/08/15 Python
python字符串,数值计算
2016/10/05 Python
使用Python搭建虚拟环境的配置方法
2018/02/28 Python
python如何实现反向迭代
2018/03/20 Python
python使用selenium登录QQ邮箱(附带滑动解锁)
2019/01/23 Python
Python中如何使用if语句处理列表实例代码
2019/02/24 Python
基于Python和PyYAML读取yaml配置文件数据
2020/01/13 Python
Python检测端口IP字符串是否合法
2020/06/05 Python
Snapfish英国:在线照片打印和个性化照片礼品
2017/01/13 全球购物
教师岗位职责
2013/11/17 职场文书
大学班级干部的自我评价分享
2014/02/10 职场文书
计生专干事迹
2014/05/28 职场文书
公司户外活动总结
2014/07/04 职场文书
校长四风对照检查材料
2014/09/27 职场文书
认识实习感想
2015/08/10 职场文书
浅谈Java父子类加载顺序
2021/08/04 Java/Android
MySQL创建管理子分区
2022/04/13 MySQL