浅析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 相关文章推荐
贴一个在Mozilla中常用的Javascript代码
Jan 09 Javascript
XRegExp 0.2: Now With Named Capture
Nov 30 Javascript
jQuery 联动日历实现代码
May 31 Javascript
在页面中js获取光标/鼠标的坐标及光标的像素坐标
Nov 11 Javascript
简单谈谈javascript中this的隐式绑定
Feb 22 Javascript
利用Mongoose让JSON数据直接插入或更新到MongoDB
May 03 Javascript
详解JS数据类型的值拷贝函数(深拷贝)
Jul 13 Javascript
node(koa2) web应用模块介绍详解
Mar 29 Javascript
javascript实现导航栏分页效果
Jun 27 Javascript
解决layer.confirm选择完之后消息框不消失的问题
Sep 16 Javascript
Vue使用NProgress进度条的方法
Sep 21 Javascript
swiperjs实现导航与tab页的联动
Dec 13 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
浅谈discuz密码加密的方式
2014/05/22 PHP
WordPress网站性能优化指南
2015/11/18 PHP
解决安装WampServer时提示缺少msvcr110.dll文件的问题
2017/07/09 PHP
PHP实现15位身份证号转18位的方法分析
2019/10/16 PHP
基于js disabled="false"不起作用的解决办法
2013/06/26 Javascript
DIV始终居中的js代码
2014/02/17 Javascript
JS 使用for循环遍历子节点查找元素
2014/09/06 Javascript
jQuery动画与特效详解
2015/02/01 Javascript
js实现数组转换成json
2015/06/26 Javascript
jQuery学习笔记之入门
2016/12/14 Javascript
详解JavaScript 新语法之Class 的私有属性与私有方法
2019/04/23 Javascript
基于jquery实现的tab选项卡功能示例【附源码下载】
2019/06/10 jQuery
微信小程序在ios下Echarts图表不能滑动的问题解决
2019/07/10 Javascript
Net微信网页开发 使用微信JS-SDK获取当前地理位置过程详解
2019/08/26 Javascript
[00:43]2016完美“圣”典风云人物:单车宣传片
2016/12/02 DOTA
[02:32]DOTA2完美大师赛场馆静安体育中心观赛全攻略
2017/11/08 DOTA
使用python统计文件行数示例分享
2014/02/21 Python
Python解析json之ValueError: Expecting property name enclosed in double quotes: line 1 column 2(char 1)
2017/07/06 Python
解决pycharm界面不能显示中文的问题
2018/05/23 Python
pycharm 将django中多个app放到同个文件夹apps的处理方法
2018/05/30 Python
学Python 3的理由和必要性
2019/11/19 Python
tornado+celery的简单使用详解
2019/12/21 Python
将matplotlib绘图嵌入pyqt的方法示例
2020/01/08 Python
使用pth文件添加Python环境变量方式
2020/05/26 Python
运行Python编写的程序方法实例
2020/10/21 Python
Html5获取高德地图定位天气的方法
2019/12/26 HTML / CSS
含预算的公司户外活动方案
2014/08/16 职场文书
胡雪岩故居导游词
2015/02/06 职场文书
法制教育观后感
2015/06/17 职场文书
如何用python插入独创性声明
2021/03/31 Python
如何用JavaScipt测网速
2021/05/09 Javascript
python 实现体质指数BMI计算
2021/05/26 Python
如何使用PyCharm及常用配置详解
2021/06/03 Python
python字典的元素访问实例详解
2021/07/21 Python
MySQL数据库必备之条件查询语句
2021/10/15 MySQL
使用Ajax实现进度条的绘制
2022/04/07 Javascript