一、JavaScript中new实现原理
1、创建一个空对象 obj
2、将该对象 obj 的原型链 __proto__ 指向构造函数的原型 prototype,
并且在原型链 __proto__ 上设置 构造函数 constructor 为要实例化的 Fn
3、传入参数,并让 构造函数 Fn 改变指向到 obj,并执行
4、最后返回 obj
 
 
二、例子:
构造函数
function Parent(age, name) {
this.age = age
this.name = name
this.sayAge = function() {
console.log('this.age :', this.age)
}
}
Parent.prototype.sayName = function() {
console.log('this.name :', this.name)
}
模拟 new 运算符功能函数
function New(Fn) {
let obj = {}
let arg = Array.prototype.slice.call(arguments, 1)
obj.__proto__ = Fn.prototype
obj.__proto__.constructor = Fn
Fn.apply(obj, arg)
return obj
}
三、测试
let son = new Parent(18, 'lining')
let newSon = New(Parent, 18, 'lining') console.log('son :', son) // son : Parent { age: 18, name: 'lining', sayAge: [Function] }
console.log('newSon :', newSon) // newSon : Parent { age: 18, name: 'lining', sayAge: [Function] } console.log('son.constructor :', son.constructor)
// son.constructor : function Parent(age, name) {
// this.age = age
// this.name = name
// this.sayAge = function() {
// console.log('this.age :', this.age)
// }
// } console.log('newSon.constructor :', newSon.constructor)
// newSon.constructor : function Parent(age, name) {
// this.age = age
// this.name = name
// this.sayAge = function() {
// console.log('this.age :', this.age)
// }
// }

四、特殊情况
上面的实现过程是一般我们所普遍知晓的构造过程
但是在 JavaScript 实现中,如果构造函数返回的是个对象/原始类型
那么最终得到的实例就不一样了
 
各个返回类型情况:
function Parent(age, name) {
this.age = age
this.name = name
this.sayAge = function() {
console.log('this.age :', this.age)
}
// return 0
// return null
// return undefined
// return false
// return true
// return ''
// return 'parent'
// return Symbol('parent')
// return []
// return {}
// return {
// hands: 2,
// foot: 2
// }
}
Parent.prototype.sayName = function() {
console.log('this.name :', this.name)
}
下面分别对应上面 11 种 return 情况
return 0:
let p1 = new Parent(18, 'jolin')
console.log('p1 :', p1) // p1 : Parent { age: 18, name: 'jolin', sayAge: [Function] } return null:
let p2 = new Parent(18, 'jolin')
console.log('p2 :', p2) // p2 : Parent { age: 18, name: 'jolin', sayAge: [Function] } return undefined:
let p3 = new Parent(18, 'jolin')
console.log('p3 :', p3) // p3 : Parent { age: 18, name: 'jolin', sayAge: [Function] } return false:
let p4 = new Parent(18, 'jolin')
console.log('p4 :', p4) // p4 : Parent { age: 18, name: 'jolin', sayAge: [Function] } return true:
let p5 = new Parent(18, 'jolin')
console.log('p5 :', p5) // p5 : Parent { age: 18, name: 'jolin', sayAge: [Function] } return '':
let p6 = new Parent(18, 'jolin')
console.log('p6 :', p6) // p6 : Parent { age: 18, name: 'jolin', sayAge: [Function] } return 'parent':
let p7 = new Parent(18, 'jolin')
console.log('p7 :', p7) // p7 : Parent { age: 18, name: 'jolin', sayAge: [Function] } return Symbol('parent'):
let p8 = new Parent(18, 'jolin')
console.log('p8 :', p8) // p8 : Parent { age: 18, name: 'jolin', sayAge: [Function] } return []:
let p9 = new Parent(18, 'jolin')
console.log('p9 :', p9) // p9 : [] return {}:
let p10 = new Parent(18, 'jolin')
console.log('p10 :', p10) // p10 : {} return {
hands: 2,
foot: 2
}
let p11 = new Parent(18, 'jolin')
console.log('p11 :', p11) // p11 : { hands: 2, foot: 2 }
因此实现原理改一下:
1、创建一个空对象 obj
2、将该对象 obj 的原型链 __proto__ 指向构造函数的原型 prototype,
并且在原型链 __proto__ 上设置 构造函数 constructor 为要实例化的 Fn
3、传入参数,并让 构造函数 Fn 改变指向到 obj,并执行
4、如果 Fn 执行后返回的是对象类型(null除外),则返回该对象,否则返回 obj

修改模拟 new 运算符功能函数

function New(Fn) {
let obj = {}
let arg = Array.prototype.slice.call(arguments, 1)
obj.__proto__ = Fn.prototype
obj.__proto__.constructor = Fn
let ret = Fn.apply(obj, arg)
return typeof ret === 'object' ? ret || obj : obj
}

JavaScript中new实现原理的更多相关文章

  1. JavaScript中的计时器原理

    理解John Resig 在 How JavaScript Timers Work. 原理分析 timer(setInterval,setTimeout)有一个很重要的概念,时间延迟的长短是不稳定的. ...

  2. JavaScript 中 this 的原理

    一.问题 学习 JavaScript 其中一个标志就是理解下面两种写法,会输出有不一样的结果. var obj = { foo: function () {} }; var foo = obj.foo ...

  3. javaScript中的闭包原理 (译)

    这篇文章通过javaScript代码解释了闭包的原理,来让编程人员理解闭包.它不是写给大牛或使用功能性语言进行编程的程序员的.一旦意会了其核心概念,闭包理解起来并不难.然而,你不可能通过阅读任何有关闭 ...

  4. 剖析Javascript中forEach()底层原理,如何重写forEach()

    我们平时用的forEach()一般是这样用的 var myArr = [1,5,8] myArr.forEach((v,i)=>{ console.log(v,i) })//运行后是这样的1 0 ...

  5. JavaScript中this对象原理简洁说明

    今天看了阮一峰大神的博客文章:JavaScript 的this原理,把纠结很久的this的指向终于理解清楚了 原文:http://www.ruanyifeng.com/blog/2018/06/jav ...

  6. JavaScript中的继承(原型链)

    一.原型链 ECMAScript中将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实例1: function SupType() { this.pro ...

  7. 领悟 JavaScript 中的面向对象

    JavaScript是基于对象的语言,我们可以使用面向对象的思想去开发js代码. JavaScript是基于对象的语言. 可以使用面向对象的思想,但是不少人对这一点理解得并不全面. 在 JavaScr ...

  8. JavaScript中this的工作原理以及注意事项

    在JavaScript中,this 的概念比较复杂.除了在面向对象编程中,this 还是随处可用的.这篇文章介绍了this 的工作原理,它会造成什么样的问题以及this 的相关例子. 要根据this  ...

  9. 原生JavaScript中动画与特效的实现原理

    现如今,许多页面上均有一些动画效果.适当的动画效果可以在一定程度上提高页面的美观度,具有提示效果的动画可以增强页面的易用性. 实现页面动画的途径一般有两种. 一种是通过操作JavaScript间接操作 ...

随机推荐

  1. easyui表格排序

    效果:点击DataGrid表格某个头部,进行升序或降序排序当前页: 问题:对应列设置  sortable:true 没有效果,刚开始以为是对应的列对应的数据库的字段类型有问题, 改动代码,使返回到前台 ...

  2. 利用nginx 反向代理解决跨域问题

    说到nginx,不得不说真的很强大,也带来很多便利用于解决一些头疼的难题. 一般来说可以用来做:静态页面的服务器.静态文件缓存服务器.网站反向代理.负载均衡服务器等等,而且实现这一切,基本只需要改改那 ...

  3. 为了约会,PM的领导能力篇来啦!

    之前我们花了很大力气阐述PM的过程能力成熟度,为的是让PM把项目管理得心应手,早点下班.可再完美的过程也要人来做啊!兄弟们要是不爽了,你还有心思约会么?那怎么才能管好组里的兄弟,让他们好好执行过程,早 ...

  4. Spark MLlib KMeans 聚类算法

    一.简介 KMeans 算法的基本思想是初始随机给定K个簇中心,按照最邻近原则把分类样本点分到各个簇.然后按平均法重新计算各个簇的质心,从而确定新的簇心.一直迭代,直到簇心的移动距离小于某个给定的值. ...

  5. django xadmin 1不在可用的选项中

    报错:1不在可用的选项中 解决办法: 对CharField的choices的选项, gender = models.CharField(max_length=, choices=((, , " ...

  6. 抽象,接口和Object类

    在面向对象的概念中, 所有的对象都是通过类来表述的, 但并不是所有的类都是用来描绘对象的, 如果一个类中么有包含足够的信息来描绘一类具体的对象, 这样的类就是抽象类. 抽象类往往用来表征对问题领域进行 ...

  7. 把ESXi中的虚拟机通过OVA/OVF导出的方式迁移到Proxmox 5

    引用地址:https://blog.csdn.net/zebra2011/article/details/83046841 一.前言    之前发现ESXi是免费的时候,非常兴奋地把几台服务器都装上了 ...

  8. commons-lang3之StringUtils

    字符串是一种在开发中经常使用到的数据类型,对字符串的处理也变得非常重要,字符串本身有一些方法,但都没有对null做处理,而且有时可能还需要做一些额外处理才能满足我们的需求,比如,要判断某个字符串中是否 ...

  9. 身边有个漂亮的java女程序员是什么体验?

    程序员都是一些追求完美的人.女程序员细致认真,不仅能写代码而且注释详尽清晰.能做好单元测试BUG最少.能写标准规范的设计文件不会对不上模块编号也不会少了类或接口说明,提交代码不会忘记写LOG,不会和测 ...

  10. java多线程编程之连续打印abc的几种解法

    一道编程题如下: 实例化三个线程,一个线程打印a,一个线程打印b,一个线程打印c,三个线程同时执行,要求打印出10个连着的abc. 题目分析: 通过题意我们可以得出,本题需要我们使用三个线程,三个线程 ...