浅析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 相关文章推荐
JQueryEasyUI datagrid框架的基本使用
Apr 08 Javascript
JavaScript实现查找字符串中第一个不重复的字符
Dec 29 Javascript
jQuery实现单击和鼠标感应事件
Feb 01 Javascript
jQuery页面加载初始化的3种方法(推荐)
Jun 02 Javascript
JavaScript算法系列之快速排序(Quicksort)算法实例详解
Sep 04 Javascript
详解React之key的使用和实践
Sep 29 Javascript
Angular2 自定义表单验证器的实现方法
Dec 14 Javascript
微信小程序中转义字符的处理方法
Mar 28 Javascript
redux.js详解及基本使用
May 24 Javascript
策略模式实现 Vue 动态表单验证的方法
Sep 16 Javascript
vue-devtools的安装和使用步骤详解
Oct 17 Javascript
react antd实现动态增减表单
Jun 03 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 Session机制简介及用法
2014/08/19 PHP
php实现发送微信模板消息的方法
2015/03/07 PHP
php通过正则表达式记取数据来读取xml的方法
2015/03/09 PHP
php精确的统计在线人数的方法
2015/10/21 PHP
TP3.2批量上传文件或图片 同名冲突问题的解决方法
2017/08/01 PHP
PHP与Web页面的交互示例详解一
2020/08/04 PHP
jQuery 相关控件的事件操作分解
2009/08/03 Javascript
JQuery中getJSON的使用方法
2010/12/13 Javascript
js中将URL中的参数提取出来作为对象的实现代码
2011/08/16 Javascript
jquery.pagination.js 无刷新分页实现步骤分享
2012/05/23 Javascript
js修改table中Td的值(定义td的双击事件)
2013/01/10 Javascript
IE下写xml文件的两种方式(fso/saveAs)
2013/08/05 Javascript
判断复选框是否被选中的两种方法
2014/06/04 Javascript
jQuery实现提交按钮点击后变成正在处理字样并禁止点击的方法
2015/03/24 Javascript
JS+CSS实现TreeMenu二级树形菜单完整实例
2015/09/18 Javascript
vue学习笔记之vue1.0和vue2.0的区别介绍
2017/05/17 Javascript
详解angularjs4部署文件过大解决过程
2018/12/05 Javascript
浅谈vue 锚点指令v-anchor的使用
2019/11/13 Javascript
Python跳出循环语句continue与break的区别
2014/08/25 Python
Python实现完整的事务操作示例
2017/06/20 Python
Python操作配置文件ini的三种方法讲解
2019/02/22 Python
jupyter notebook参数化运行python方式
2020/04/10 Python
Python基于opencv的简单图像轮廓形状识别(全网最简单最少代码)
2021/01/28 Python
纯CSS3制作漂亮带动画效果的主机价格表
2015/04/25 HTML / CSS
实例讲解CSS3中的border-radius属性
2015/08/18 HTML / CSS
CSS3 实现弹跳的小球动画
2020/10/26 HTML / CSS
HTML5实现文件断点续传的方法
2017/01/04 HTML / CSS
Kathmandu英国网站:新西兰户外运动品牌
2017/03/27 全球购物
Lou & Grey美国官网:主打舒适性面料服饰
2017/12/21 全球购物
Static Nested Class 和 Inner Class的不同
2013/11/28 面试题
文明餐桌活动方案
2014/02/11 职场文书
酒店员工职业生涯规划
2014/02/25 职场文书
《日月潭》教学反思
2014/02/28 职场文书
买卖协议书范本
2014/04/21 职场文书
建设工程授权委托书
2014/09/22 职场文书
重阳节主题班会
2015/08/17 职场文书