浅析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 相关文章推荐
node.js chat程序如何实现Ajax long-polling长链接刷新模式
Mar 13 Javascript
onclick与listeners的执行先后问题详细解剖
Jan 07 Javascript
JS简单实现登陆验证附效果图
Nov 19 Javascript
bootstrap table 服务器端分页例子分享
Feb 10 Javascript
JavaScript中的getDay()方法使用详解
Jun 09 Javascript
Javascript验证方法大全
Sep 21 Javascript
如何使用jquery实现文字上下滚动效果
Oct 12 Javascript
浅析上传头像示例及其注意事项
Dec 14 Javascript
详解Typescript 内置的模块导入兼容方式
May 31 Javascript
vue.js页面加载执行created,mounted的先后顺序说明
Nov 07 Javascript
echarts柱状图背景重叠组合而非并列的实现代码
Dec 10 Javascript
Web应用开发TypeScript使用详解
May 25 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(4) php 函数 补充2
2010/02/15 PHP
php中禁止单个IP与ip段访问的代码小结
2012/07/04 PHP
thinkPHP实现签到功能的方法
2017/03/15 PHP
JavaScript进阶教程(第四课第一部分)
2007/04/05 Javascript
有道JavaScript监听浏览器的问题
2010/06/23 Javascript
jquery中文乱码的多种解决方法
2013/06/21 Javascript
js控制表单操作的常用代码小结
2013/08/15 Javascript
jQuery中hasClass()方法用法实例
2015/01/06 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
2015/01/28 Javascript
尝试动手制作javascript放大镜效果
2015/12/25 Javascript
详解Bootstrap的aria-label和aria-labelledby应用
2016/01/04 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
AngularJS实现数据列表的增加、删除和上移下移等功能实例
2016/09/05 Javascript
js表单登陆验证示例
2016/10/19 Javascript
详解IWinter 一个路由转控制器的 Nodejs 库
2017/11/15 NodeJs
Vue.js在数组中插入重复数据的实现代码
2017/11/17 Javascript
通过函数作用域和块级作用域看javascript的作用域链
2018/08/05 Javascript
vue设置一开始进入的页面教程
2019/10/28 Javascript
react PropTypes校验传递的值操作示例
2020/04/28 Javascript
Python实现各种排序算法的代码示例总结
2015/12/11 Python
python读取文件名称生成list的方法
2018/04/27 Python
matplotlib savefig 保存图片大小的实例
2018/05/24 Python
深入解析Python小白学习【操作列表】
2019/03/23 Python
django 取消csrf限制的实例
2020/03/13 Python
Numpy 理解ndarray对象的示例代码
2020/04/03 Python
python+flask编写一个简单的登录接口
2020/11/13 Python
植村秀美国官网:Shu Uemura美国
2019/03/19 全球购物
高校学生干部的自我评价分享
2013/11/04 职场文书
九年级科学教学反思
2014/01/29 职场文书
实验教师岗位职责
2014/02/13 职场文书
德语专业求职信
2014/03/12 职场文书
2015年七七事变78周年纪念活动方案
2015/05/06 职场文书
爸爸的三轮车观后感
2015/06/16 职场文书
廉洁自律证明
2015/06/24 职场文书
字典算法实现及操作 --python(实用)
2021/03/31 Python
JS前端监控采集用户行为的N种姿势
2022/07/23 Javascript