浅析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 相关文章推荐
jquery tab插件制作实现代码
Jun 22 Javascript
js实现广告漂浮效果的小例子
Jul 02 Javascript
JavaScript中访问节点对象的方法有哪些如何使用
Sep 24 Javascript
深入理解JavaScript系列(48):对象创建模式(下篇)
Mar 04 Javascript
Prototype框架详解
Nov 25 Javascript
jquery编写Tab选项卡滚动导航切换特效
Jul 17 Javascript
canvas实现钟表效果
Feb 13 Javascript
Bootstrap.css与layDate日期选择样式起冲突的解决办法
Apr 07 Javascript
JavaScript中常见的八个陷阱总结
Jun 28 Javascript
Angular4如何自定义首屏的加载动画详解
Jul 26 Javascript
ES6模板字符串和标签模板的应用实例分析
Jun 25 Javascript
Openlayers+EasyUI Tree动态实现图层控制
Sep 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
各种咖啡的英文名子是什么
2021/03/03 新手入门
解析php DOMElement 操作xml 文档的实现代码
2013/05/10 PHP
PHP中字符安全过滤函数使用小结
2015/02/25 PHP
php计算税后工资的方法
2015/07/28 PHP
asp 的 分词实现代码
2007/05/24 Javascript
JavaScript 验证浏览器是否支持javascript的方法小结
2009/05/17 Javascript
MooTools 1.2介绍
2009/09/14 Javascript
js实现页面打印功能实例代码(附去页眉页脚功能代码)
2009/12/15 Javascript
js动态添加事件并可传参数示例代码
2013/10/21 Javascript
通过js简单实现将一个文本内容转译成加密文本
2013/10/22 Javascript
jquery实现二级导航下拉菜单效果
2015/12/18 Javascript
实例讲解JavaScript中的this指向错误解决方法
2016/06/13 Javascript
微信小程序开发的四十个技术窍门总结(推荐)
2017/01/23 Javascript
JS正则获取HTML元素的方法
2017/03/31 Javascript
Bootstrap Tree View简单而优雅的树结构组件实例解析
2017/06/15 Javascript
angular1配合gulp和bower的使用教程
2018/01/19 Javascript
JavaScript中 ES6变量的结构赋值
2018/07/10 Javascript
vue路由跳转传递参数的方式总结
2020/05/10 Javascript
如何将Node.js中的回调转换为Promise
2020/11/10 Javascript
实用的 vue tags 创建缓存导航的过程实现
2020/12/03 Vue.js
[43:58]DOTA2上海特级锦标赛C组败者赛 Newbee VS Archon第二局
2016/02/27 DOTA
python使用rpc框架gRPC的方法
2018/08/24 Python
python tornado修改log输出方式
2019/11/18 Python
Python二次规划和线性规划使用实例
2019/12/09 Python
Python 解码Base64 得到码流格式文本实例
2020/01/09 Python
pytorch 状态字典:state_dict使用详解
2020/01/17 Python
Scrapy框架实现的登录网站操作示例
2020/02/06 Python
Python多线程操作之互斥锁、递归锁、信号量、事件实例详解
2020/03/24 Python
浅谈Python 钉钉报警必备知识系统讲解
2020/08/17 Python
HTML5制作酷炫音频播放器插件图文教程
2014/12/30 HTML / CSS
在阿尔卑斯山或希腊度过快乐假期:Alpine Elements
2019/12/28 全球购物
编写一个类体现构造,公有,私有方法,静态,私有变量
2013/08/10 面试题
艾滋病宣传活动总结
2014/05/08 职场文书
读书之星事迹材料
2014/05/12 职场文书
无线电知识基础入门篇
2022/02/18 无线电
Java8 Stream API 提供了一种高效且易于使用的处理数据的方式
2022/04/13 Java/Android