浅析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 相关文章推荐
IE8 兼容性问题(属性名区分大小写)
Jun 04 Javascript
jsvascript图像处理—(计算机视觉应用)图像金字塔
Jan 15 Javascript
JavaScript闭包实例讲解
Apr 22 Javascript
NODE.JS加密模块CRYPTO常用方法介绍
Jun 05 Javascript
jQuery 中$(this).index与$.each的使用指南
Nov 20 Javascript
深入分析JSONP跨域的原理
Dec 10 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(二)之数据支持json字符串、list集合
Aug 11 Javascript
jquery表格datatables实例解析 直接加载和延迟加载
Aug 12 Javascript
javascript深拷贝、浅拷贝和循环引用深入理解
May 27 Javascript
浅谈vue加载优化策略
Mar 19 Javascript
layui checkbox默认选中,获取选中值,清空所有选中项的例子
Sep 02 Javascript
JavaScript动画实例之粒子文本的实现方法详解
Jul 28 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 fsockopen中多线程问题的解决办法[翻译]
2011/11/09 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
2019/12/20 PHP
一种JavaScript的设计模式
2006/11/22 Javascript
jQuery的实现原理的模拟代码 -4 重要的扩展函数 extend
2010/08/03 Javascript
JavaScript 设计模式 安全沙箱模式
2010/09/24 Javascript
JavaScript学习点滴 call、apply的区别
2010/10/22 Javascript
浅析Prototype的模板类 Template
2011/12/07 Javascript
javascript当中的代码嗅探扩展原生对象和原型(prototype)
2013/01/11 Javascript
javascript中typeof的使用示例
2013/12/19 Javascript
JavaScript自定义数组排序方法
2015/02/12 Javascript
Jquery实现鼠标移动放大图片功能实例
2015/03/25 Javascript
JSONObject使用方法详解
2015/12/17 Javascript
js采用concat和sort将N个数组拼接起来的方法
2016/01/21 Javascript
vue.js 使用axios实现下载功能的示例
2018/03/05 Javascript
vue鼠标移入添加class样式,鼠标移出去除样式(active)实现方法
2018/08/22 Javascript
vue + any-touch实现一个iscroll 实现拖拽和滑动动画效果
2019/04/08 Javascript
JS桶排序的简单理解与实现方法示例
2019/11/25 Javascript
浅谈vant组件Picker 选择器选单选问题
2020/11/04 Javascript
详解JavaScript原型与原型链
2020/11/16 Javascript
JavaScript实现滑块验证解锁
2021/01/07 Javascript
[01:04:08]完美世界DOTA2联赛PWL S3 INK ICE vs GXR 第一场 12.16
2020/12/18 DOTA
python冒泡排序算法的实现代码
2013/11/21 Python
python的三目运算符和not in运算符使用示例
2014/03/03 Python
分享一个常用的Python模拟登陆类
2015/03/29 Python
Python使用defaultdict读取文件各列的方法
2017/05/11 Python
python中学习K-Means和图片压缩
2017/11/20 Python
Python3.6实现根据电影名称(支持电视剧名称),获取下载链接的方法
2019/08/26 Python
使用Python的datetime库处理时间(RPA流程)
2019/11/24 Python
Tensorflow tf.nn.atrous_conv2d如何实现空洞卷积的
2020/04/20 Python
利用CSS3实现自定义滚动条代码分享
2016/08/18 HTML / CSS
HTML5网页音乐播放器的示例代码
2017/11/09 HTML / CSS
Wedgwood美国官网:英国骨瓷,精美礼品及家居装饰
2018/02/17 全球购物
一年级学生期末评语
2014/04/21 职场文书
预备党员综合考察材料
2014/05/31 职场文书
实习指导老师意见
2015/06/04 职场文书
签字仪式主持词
2015/07/03 职场文书