提到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的实现原理及重写相关推荐

  1. JS中的new操作符原理解析

    JS中的new操作符原理解析 new操作符做了什么 参考 推荐阅读 你越是认真生活,你的生活就会越美好--弗兰克·劳埃德·莱特 <人生果实>经典语录 new操作符做了什么 var Pers ...

  2. 深入理解js中实现继承的原理和方法

    原型对象继承 原理:原型对象的属性可以经由对象实例访问 下面的例子,所含[对象继承]和[构造函数继承],用于理解[原型属性经由对象实例访问] //对象继承 var person = {name:&qu ...

  3. 解析Vue.js中的computed工作原理

    我们通过实现一个简单版的和Vue中computed具有相同功能的函数来了解computed是如何工作的.写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指 ...

  4. js中flat方法的实现原理

    Array.prototype.flat(),将多维数组降维 let arr = [1, [2, 3, [4, 5, [12, 3, "zs"], 7, [8, 9, [10, 1 ...

  5. JS 中的 this

    JS中的this 本文是本人阅读MDN文档和Dmitri Pavlutin的博客后写下的this学习笔记, 主要翻译自Dmitri Pavlutin的博客 Gentle Explanation of ...

  6. php new对象 调用函数,关于JS中new调用函数的原理介绍

    这篇文章主要介绍了关于JS中new调用函数的原理介绍,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 JavaScript 中经常使用构造函数创建对象(通过 new 操作符调用一个函数) ...

  7. android重写方法,android中native js中重写方法问题

    java代码: PhoneStateListener phoneStateListener = new PhoneStateListener() { @Override public void onS ...

  8. js中几种实用的跨域方法原理详解

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  9. js中 new原理及实现

    在js中,我们通过new运算符来创建一个对象,它是一个高频的操作.我们一般只是去用它,而很少关注它是如何实现的,它的工作机制是什么. 1 简介 本文介绍new的功能,用法,补充介绍不加new也同样也创 ...

最新文章

  1. [POJ 3270]Cow Sorting
  2. duilib控件的一些属性
  3. VTK:IO之FindAllArrayNames
  4. springboot约定优于配置的体现
  5. Linux虚拟文件系统(VFS)
  6. 信息学奥赛C++语言:质数
  7. 智能机维修暴利大起底:触摸屏成本30维修300元
  8. BitMEX联合创始人:以比特币为首的加密货币综合体是防范恶性通货膨胀的最佳对冲
  9. centos yum安装php5.5,奇妙伞-Centos下使用yum安装PHP5.5,5.6,7.0
  10. CnCiswumWN
  11. windows10安装nodeJs及环境配置
  12. linux运行bak,linux 备份学习
  13. 中兴B860AV2.1刷Armbian折腾记录
  14. 云空间插虾米html音乐,总结一下可以上传MP3并外链的空间
  15. 竞价单页设计需要了解的知识
  16. IDEA 运行 springboot运行出现 错误: 找不到或无法加载主类和找不到资源文件类
  17. 云原生之使用docker部署centos系统测试环境
  18. 利用libjpeg库实现jpg与bmp图片互转指南
  19. 【数据结构】堆和二叉堆
  20. 《Python开发 - Python杂记》Python与C/C++混合编程

热门文章

  1. 百度google关键字优化的小技巧
  2. linux网络配置命令 ifconfig 、route 、ip 、ip route
  3. IDEA中Alt + Insert快捷键定制生成类方法
  4. 【今日CS 视觉论文速览】Tue, 15 Jan 2019
  5. Echarts 地理信息可视化:基于地图显示坐标点信息
  6. Kubernetes-服务连接和暴露(endpoints)(二十)
  7. 使用Thread类来创建线程
  8. pptx给幻灯片添加内容
  9. linux-vim设置环境
  10. explain for connection用法