浅析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 相关文章推荐
超级兔子让浮动层消失的前因后果
Mar 09 Javascript
Prototype Array对象 学习
Jul 19 Javascript
Jquery Autocomplete 结合asp.net使用要点
Oct 29 Javascript
jQuery遍历之next()、nextAll()方法使用实例
Nov 08 Javascript
JS给超链接加确认对话框的方法
Feb 24 Javascript
js实现宇宙星空背景效果的方法
Mar 03 Javascript
js实现简单的联动菜单效果
Aug 19 Javascript
浅谈jQuery的bind和unbind事件(绑定和解绑事件)
Mar 02 Javascript
Node.js 实现简单的接口服务器的实例代码
May 23 Javascript
vue实现页面加载动画效果
Sep 19 Javascript
React 使用browserHistory项目访问404问题解决
Jun 01 Javascript
JavaScript indexOf()原理及使用方法详解
Jul 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函数解决SQL injection
2006/12/09 PHP
dede3.1分页文字采集过滤规则详说(图文教程)续四
2007/04/03 PHP
ecshop 订单确认中显示省市地址信息的方法
2010/03/15 PHP
Fine Uploader文件上传组件应用介绍
2013/01/06 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(二)
2014/06/23 PHP
Laravel框架处理用户的请求操作详解
2019/12/20 PHP
用cssText批量修改样式
2009/08/29 Javascript
jQuery DOM操作小结与实例
2010/01/07 Javascript
jQuery 瀑布流 绝对定位布局(二)(延迟AJAX加载图片)
2012/05/23 Javascript
JQuery 动态生成Table表格实例代码
2016/12/02 Javascript
利用VUE框架,实现列表分页功能示例代码
2017/01/12 Javascript
Angular.Js之Scope作用域的学习教程
2017/04/27 Javascript
Vue.js实现按钮的动态绑定效果及实现代码
2017/08/21 Javascript
Angular 5.x 学习笔记之Router(路由)应用
2018/04/08 Javascript
JS简单实现动态添加HTML标记的方法示例
2018/04/08 Javascript
学习React中ref的两个demo示例
2018/08/14 Javascript
jsonp跨域及实现百度首页联想功能的方法
2018/08/30 Javascript
如何从零开始手写Koa2框架
2019/03/22 Javascript
countup.js实现数字动态叠加效果
2019/10/17 Javascript
Vue打包后访问静态资源路径问题
2019/11/08 Javascript
Nuxt默认模板、默认布局和自定义错误页面的实现
2020/05/11 Javascript
如何阻止移动端浏览器点击图片浏览
2020/08/29 Javascript
Python数组定义方法
2016/04/13 Python
pytorch载入预训练模型后,实现训练指定层
2020/01/06 Python
python手写均值滤波
2020/02/19 Python
Python爬虫实现模拟点击动态页面
2020/03/05 Python
Python可以实现栈的结构吗
2020/05/27 Python
大专生找工作自荐书
2014/06/10 职场文书
党员批评与自我批评思想汇报(集锦)
2014/09/14 职场文书
吃空饷专项整治方案
2014/10/27 职场文书
幼儿园门卫安全责任书
2015/05/08 职场文书
2015年幼儿园中班开学寄语
2015/05/27 职场文书
债务追讨律师函
2015/06/24 职场文书
如何用python插入独创性声明
2021/03/31 Python
pandas数值排序的实现实例
2021/07/25 Python
windows server2008 开启端口的实现方法
2022/06/25 Servers