浅析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 相关文章推荐
javascript 手动给表增加数据的小例子
Jul 10 Javascript
使用JS CSS去除IE链接虚线框的三种方法
Nov 14 Javascript
jQuery DOM删除节点操作指南
Mar 03 Javascript
Express的路由详解
Dec 10 Javascript
微信小程序 SocketIO 实例讲解
Oct 13 Javascript
jQuery常见面试题之DOM操作详析
Jul 05 jQuery
vue.js异步上传文件前后端实现代码
Aug 22 Javascript
纯JavaScript实现实时反馈系统时间
Oct 26 Javascript
vue中倒计时组件的实例代码
Jul 06 Javascript
详解vue.js移动端配置flexible.js及注意事项
Apr 10 Javascript
vue element 关闭当前tab 跳转到上一路由操作
Jul 22 Javascript
浅谈JS的二进制家族
May 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上传文件并显示上传进度的方法
2015/03/24 PHP
PHP终止脚本运行三种实现方法详解
2020/09/01 PHP
JQuery 常用方法基础教程
2009/02/06 Javascript
基于jquery实现后台左侧菜单点击上下滑动显示
2013/04/11 Javascript
jquery遍历筛选数组的几种方法和遍历解析json对象
2013/12/13 Javascript
js实现人民币大写金额形式转换
2016/04/27 Javascript
JS非空验证及邮箱验证的实例
2017/08/11 Javascript
react-native DatePicker日期选择组件的实现代码
2017/09/12 Javascript
微信小程序下拉刷新PullDownRefresh的使用方法
2018/11/29 Javascript
基于vue-cli、elementUI的Vue超简单入门小例子(推荐)
2019/04/17 Javascript
vue实现在线翻译功能
2019/09/27 Javascript
javascript 模块依赖管理的本质深入详解
2020/04/30 Javascript
实例讲解React 组件
2020/07/07 Javascript
JavaScript中CreateTextFile函数
2020/08/30 Javascript
解决vue-loader加载不上的问题
2020/10/21 Javascript
python 利用turtle模块画出没有角的方格
2019/11/23 Python
python 比较2张图片的相似度的方法示例
2019/12/18 Python
tensorflow的计算图总结
2020/01/12 Python
Tensorflow轻松实现XOR运算的方式
2020/02/03 Python
PyQt5的相对布局管理的实现
2020/08/07 Python
欧洲最大的婴幼儿服装及内衣公司:Petit Bateau(小帆船)
2016/08/16 全球购物
英国剑桥包中文官网:The Cambridge Satchel Company中国
2018/11/06 全球购物
什么是Web Service?
2012/07/25 面试题
thinkphp5 redis缓存新增方法实例讲解
2021/03/24 PHP
电子商务专业毕业生工作推荐信
2013/11/17 职场文书
银行出纳岗位职责
2013/11/25 职场文书
建筑文秘专业个人求职信范文
2013/12/28 职场文书
生态养殖创业计划书
2014/05/06 职场文书
小学竞选班干部演讲稿
2014/08/20 职场文书
争先创优公开承诺书
2014/08/30 职场文书
小班下学期幼儿评语
2014/12/30 职场文书
2015廉洁自律个人总结
2015/02/14 职场文书
德能勤绩工作总结
2015/08/11 职场文书
2016年推广普通话宣传周活动总结
2016/04/06 职场文书
详解在OpenCV中如何使用图像像素
2022/03/03 Python
Python如何快速找到多个字典中的公共键(key)
2022/04/29 Python