JS中new的实现原理及重写
提到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的实现原理及重写的更多相关文章
- 详解 JS 中 new 调用函数原理
JavaScript 中经常使用构造函数创建对象(通过 new 操作符调用一个函数),那在使用 new 调用一个函数的时候到底发生了什么?先看几个例子,再解释背后发生了什么. 1)看三个例子 1.1 ...
- 在jsp页面的js中使用Cookie的原理介绍以及相应方法的代码
1. 设置cookie 1.1 每个cookie都是一个名/值对,可以把下面这样一个字符串赋值给document.cookie: document.cookie="user_Id=828&q ...
- 解析Vue.js中的computed工作原理
我们通过实现一个简单版的和Vue中computed具有相同功能的函数来了解computed是如何工作的.写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指 ...
- jQuery的封装方式与JS中new的实现原理
function jQuery() { return new jQuery.fn.init(); } jQuery.fn = jQuery.prototype = { init: function() ...
- JS中的new操作符原理解析
var Person = function(name){ this.name = name; } Person.prototype.sayHello = function() { console.lo ...
- 深入理解JS中的对象(二):new 的工作原理
目录 序言 不同返回值的构造函数 深入 new 调用函数原理 总结 参考 1.序言 在 深入理解JS中的对象(一):原型.原型链和构造函数 中,我们分析了JS中是否一切皆对象以及对象的原型.原型链和构 ...
- js中几种实用的跨域方法原理详解(转)
今天研究js跨域问题的时候发现一篇好博,非常详细地讲解了js几种跨域方法的原理,特分享一下. 原博地址:http://www.cnblogs.com/2050/p/3191744.html 下面正文开 ...
- js中几种实用的跨域方法原理详解
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- paip.编程语言方法重载实现的原理及python,php,js中实现方法重载
paip.编程语言方法重载实现的原理及python,php,js中实现方法重载 有些语言,在方法的重载上,形式上不支持函数重载,但可以通过模拟实现.. 主要原理:根据参数个数进行重载,或者使用默认值 ...
随机推荐
- typedef声明变量也是一种求值过程
前言: 什么叫做:声明变量是求值过程?请看下面的声明, int i; 很简单,声明了个整型变量i,再看如下声明, int *p; 也很简单,立刻反应出来它是指向整型的指针,但是具体如何推倒出来的呢?其 ...
- jade 的 考古
Jade是一款高性能简洁易懂的模板引擎(加上这两个字我想起了发动机,为什么不直接叫发动机呢), Jade是Haml的Javascript实现, 在服务端(NodeJS)及客户端均有支持. haml 是 ...
- Linux上部署web服务器并发布web项目-转
Linux上部署web服务器并发布web项目 近在学习如何在linux上搭建web服务器来发布web项目,由于本人是linux新手,所以中间入了不少坑,搞了好久才搞出点成果.以下是具体的详细步骤以 ...
- 基于云开发开发 Web 应用(一):项目介绍 & 初始化
基于云开发开发 Web 应用(一):项目介绍 & 初始化 背景描述 Linux 中国曾在过去的 1 - 2 年内长期运行了一个 TL;DR 的中国版.不过当时做的版本是小程序的版本,一直以来, ...
- es6的promise用法详解
es6的promise用法详解 promise 原理 promise是es6的异步编程解决方案, 是es6封装好的对象: 一个promise有三种状态:Pending(进行中).Resolved(已完 ...
- mybatis generator cmd 终端命令 生成dao model mapper
mybatis generator cmd 终端命令 生成dao model mapper 文件包下载 mybatis-generator-core-1.3.2.jar 下载地址:https://gi ...
- c语言秋季作业3
本周作业头 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 作业链接 我在这个课程的目标是 运用C语言编程解决一些简单的数学问题 这个作业在那个具体方面帮助我实现目标 学习if else ...
- pycharm版本下载地址
https://www.runoob.com/w3cnote/pycharm-windows-install.html 下载社区版本,因为免费 其余按照默认安装即可
- 共轭先验(conjugate prior)
共轭是贝叶斯理论中的一个概念,一般共轭要说是一个先验分布与似然函数共轭: 那么就从贝叶斯理论中的先验概率,后验概率以及似然函数说起: 在概率论中有一个条件概率公式,有两个变量第一个是A,第二个是B , ...
- 在Centos7上安装Oracle
环境: 硬盘30G:2G RAM:Centos7:Oracle 11G: 1.创建组和用户 [zzd@localhost ~]$ su root #切换到root Password: [root@lo ...