浅析JS中NEW的实现原理及重写


Posted in Javascript onFebruary 20, 2020

提到new,肯定会和类和实例联系起来,如:

function Func() {
 let x = 100;
 this.num = x +
}
let f = new Func();

上面的代码,我们首先创建了一个函数,如果是用面向对象的说法就是创建了一个Function类的实例,如果直接执行这个函数,那它就是一个普通的函数,如果用new执行,则这个函数被称为一个自定义的类。

如果是一个普通函数执行,他会如下做几件事:

·形成一个全新的执行上下文EC(Execution Context 执行环境)

·形成一个AO(Activation Object 活动对象)变量对象,初始化arguments和形参赋值

·初始化作用域链

·代码执行

如果是new函数执行,它既有普通函数执行的一面,也有自己独有的东西:

·默认创建一个对象,而这个对象就是当前类的实例

·声明其this指向,让其指向这个新创建的实例

·不论其是否写return,都会把新创建的实例返回,这里有个特殊点,如果用户自己返回内容,且返回的是一个引用类型值,则会把默认返回的实例给覆盖掉,此时返回的值就不再是类的实例了

console.log(f); //=>{num:200}
//f是Func这个类的实例 
//相当于给创建的实例对象新增一个num的属性 obj.num=200 (因为具备普通函数执行的一面,所以只有this.xxx=xxx才和创建的实例有关系,此案例中的x只是AO中的私有变量)
console.log(f instanceof Func); //=>TRUE instanceof用来检测某一个实例是否属于这个类

每一次new出来的都是一个新的实例对象

console.log(f === f2); //=>false

既然知道了new都做了什么事情,我们重新一下new:

/* 
 * 内置NEW的实现原理 
 * @params
 *  Func:操作的那个类
 *  ARGS:NEW类的时候传递的实参集合
 * @return
 *  实例或者自己返回的对象
 */
function _new(Func, ...args) {
  //默认创建一个实例对象(而且是属于当前这个类的一个实例)
  let obj = {};

  //也会把类当做普通函数执行
  //执行的时候要保证函数中的this指向创建的实例
  let result = Func.call(obj, ...args);

  //若客户自己返回引用值,则以自己返回的为主,否则返回创建的实例
  if ((result !== null && typeof result === "object") || (typeof result === "function")) {
    return result;
  }
  return obj;
}

我们试一下:

let f3 = _new(Func);
console.log(f3); // =>{num: 200}

我们继续测试:

Func.prototype.log = function () {
  console.log('ok');
}
let f4 = _new(Func);
f4.log(); //=>Uncaught TypeError: f4.log is not a function

也就是说,Func原型上的方法其实例没法调用,我们还需要修改:

/* 
 * 内置NEW的实现原理 
 * @params
 *  Func:操作的那个类
 *  ARGS:NEW类的时候传递的实参集合
 * @return
 *  实例或者自己返回的对象
 */
function _new(Func, ...args) {
  //默认创建一个实例对象(而且是属于当前这个类的一个实例)
  // let obj = {};
  let obj = Object.create(Func.prototype);

  //也会把类当做普通函数执行
  //执行的时候要保证函数中的this指向创建的实例
  let result = Func.call(obj, ...args);

  //若客户自己返回引用值,则以自己返回的为主,否则返回创建的实例
  if ((result !== null && typeof result === "object") || (typeof result === "function")) {
    return result;
  }
  return obj;
}

这样应该就可以了。

let f6 = _new(Func);
f6.log(); //=>ok

总结

以上所述是小编给大家介绍的JS中NEW的实现原理及重写,希望对大家有所帮助,也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
新浪的图片新闻效果
Jan 13 Javascript
extjs中grid中嵌入动态combobox的应用
Jan 01 Javascript
利用React-router+Webpack快速构建react程序
Oct 27 Javascript
Bootstrap缩略图与警告框学习使用
Feb 08 Javascript
Vue Socket.io源码解读
Feb 07 Javascript
Vue.js 实现微信公众号菜单编辑器功能(一)
May 08 Javascript
vue-cli 引入、配置axios的方法
May 08 Javascript
JS实现的JSON序列化操作简单示例
Jul 02 Javascript
Vue文件配置全局变量的实例
Sep 06 Javascript
layer.alert自定义关闭回调事件的方法
Sep 27 Javascript
VUE使用axios调用后台API接口的方法
Aug 03 Javascript
vue使用echarts实现水平柱形图实例
Sep 09 Javascript
JS通过识别id、value值对checkbox设置选中状态
Feb 19 #Javascript
Javascript实现html转pdf高清版(提高分辨率)
Feb 19 #Javascript
Vue组件模板的几种书写形式(3种)
Feb 19 #Javascript
详解Vue 单文件组件的三种写法
Feb 19 #Javascript
vue中 v-for循环的用法详解
Feb 19 #Javascript
vue 使用v-for进行循环的实例代码详解
Feb 19 #Javascript
JS操作Fckeditor的一些常用方法(获取、插入等)
Feb 19 #Javascript
You might like
PHP数组及条件,循环语句学习
2012/11/11 PHP
从零开始学YII2框架(二)通过 Composer 安装扩展插件
2014/08/20 PHP
php实现的二叉树遍历算法示例
2017/06/15 PHP
centos7上编译安装php7以php-fpm方式连接apache
2018/11/08 PHP
Laravel核心解读之异常处理的实践过程
2019/02/24 PHP
php的instanceof和判断闭包Closure操作示例
2020/01/26 PHP
自己的js工具_Form 封装
2009/08/21 Javascript
javascript整除实现代码
2010/11/23 Javascript
jquery实现html页面 div 假分页有原理有代码
2014/09/06 Javascript
js实现按Ctrl+Enter发送效果
2014/09/18 Javascript
JS模拟键盘打字效果的方法
2015/08/05 Javascript
AngularJs bootstrap搭载前台框架——准备工作
2016/09/01 Javascript
微信小程序 网络API发起请求详解
2016/11/09 Javascript
玩转NODE.JS(四)-搭建简单的聊天室的代码
2016/11/11 Javascript
原生js实现秒表计时器功能
2017/02/16 Javascript
微信小程序实现下拉刷新和轮播图效果
2017/11/21 Javascript
NodeJS简单实现WebSocket功能示例
2018/02/10 NodeJs
小程序封装wx.request请求并创建接口管理文件的实现
2019/04/29 Javascript
js数组相减简单示例【删除a数组所有与b数组相同元素】
2020/03/04 Javascript
Python批处理更改文件名os.rename的方法
2018/10/26 Python
pandas DataFrame的修改方法(值、列、索引)
2019/08/02 Python
解决python多行注释引发缩进错误的问题
2019/08/23 Python
python提取xml里面的链接源码详解
2019/10/15 Python
英国豪华文具和皮具配件经典老品牌:Smythson(斯迈森)
2018/04/19 全球购物
新奥尔良珠宝:Mignon Faget
2020/11/23 全球购物
自我鉴定范文
2013/11/10 职场文书
人民调解员先进事迹材料
2014/05/08 职场文书
三方股东合作协议书范本
2014/09/28 职场文书
优秀党员先进材料
2014/12/18 职场文书
表扬信格式模板
2015/05/05 职场文书
惊天动地观后感
2015/06/10 职场文书
三下乡活动心得体会
2016/01/23 职场文书
委托开发合同书(标准版)
2019/08/07 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书
2020年个人安全保证书参考模板
2020/01/08 职场文书
教你用Java在个人电脑上实现微信扫码支付
2021/06/13 Java/Android