JS重学系列之聊聊new操作符


Posted in Javascript onMarch 04, 2019

new操作符的基本过程:

1.创建一个新的空对象。

2.将构造函数的作用域赋给它(即this指向它)。

3.新对象增加构造函数的基本方法和属性。

4.返回新对象

上面的过程大家应该都熟悉,本文是重学 JS 系列的第一篇文章,写这个系列的初衷也是为了夯实自己的 JS 基础。既然是重学,肯定不会从零开始介绍一个知识点,如有遇到不会的内容请自行查找资料。

new 的作用

我们先来通过两个例子来了解 new 的作用

function Test(name) {
 this.name = name
}
Test.prototype.sayName = function () {
 console.log(this.name)
}
const t = new Test('yck')
console.log(t.name) // 'yck'
t.sayName() // 'yck'

从上面一个例子中我们可以得出这些结论:

  • new 通过构造函数 Test 创建出来的实例可以访问到构造函数中的属性
  • new 通过构造函数 Test 创建出来的实例可以访问到构造函数原型链中的属性,也就是说通过 new 操作符,实例与构造函数通过原型链连接了起来

但是当下的构造函数 Test 并没有显式 return 任何值(默认返回 undefined),如果我们让它返回值会发生什么事情呢?

function Test(name) {
 this.name = name
 return 1
}
const t = new Test('yck')
console.log(t.name) // 'yck'

虽然上述例子中的构造函数中返回了 1,但是这个返回值并没有任何的用处,得到的结果还是和之前的例子完全一样。

那么通过这个例子,我们又可以得出一个结论:

  • 构造函数如果返回原始值(虽然例子中只有返回了 1,但是你可以试试其他的原始值,结果还是一样的),那么这个返回值毫无意义

试完了返回原始值,我们再来试试返回对象会发生什么事情吧

function Test(name) {
 this.name = name
 console.log(this) // Test { name: 'yck' }
 return { age: 26 }
}
const t = new Test('yck')
console.log(t) // { age: 26 }
console.log(t.name) // 'undefined'

通过这个例子我们可以发现,虽然构造函数内部的 this 还是依旧正常工作的,但是当返回值为对象时,这个返回值就会被正常的返回出去。

那么通过这个例子,我们再次得出了一个结论:

  • 构造函数如果返回值为对象,那么这个返回值会被正常使用

这两个例子告诉了我们一点,构造函数尽量不要返回值。因为返回原始值不会生效,返回对象会导致 new 操作符没有作用。

通过以上几个例子,相信大家也大致了解了 new 操作符的作用了,接下来我们就来尝试自己实现 new 操作符。

自己实现 new 操作符

首先我们再来回顾下 new 操作符的几个作用

  • new 操作符会返回一个对象,所以我们需要在内部创建一个对象
  • 这个对象,也就是构造函数中的 this,可以访问到挂载在 this 上的任意属性
  • 这个对象可以访问到构造函数原型上的属性,所以需要将对象与构造函数链接起来
  • 返回原始值需要忽略,返回对象需要正常处理

回顾了这些作用,我们就可以着手来实现功能了

function create(Con, ...args) {
 let obj = {}
 Object.setPrototypeOf(obj, Con.prototype)
 let result = Con.apply(obj, args)
 return result instanceof Object ? result : obj
}

这就是一个完整的实现代码,我们通过以下几个步骤实现了它:

  • 首先函数接受不定量的参数,第一个参数为构造函数,接下来的参数被构造函数使用
  • 然后内部创建一个空对象 obj
  • 因为 obj 对象需要访问到构造函数原型链上的属性,所以我们通过 setPrototypeOf 将两者联系起来。这段代码等同于 obj.__proto__ = Con.prototype
  • 将 obj 绑定到构造函数上,并且传入剩余的参数
  • 判断构造函数返回值是否为对象,如果为对象就使用构造函数返回的值,否则使用 obj,这样就实现了忽略构造函数返回的原始值

接下来我们来使用下该函数,看看行为是否和 new 操作符一致

function Test(name, age) {
 this.name = name
 this.age = age
}
Test.prototype.sayName = function () {
 console.log(this.name)
}
const a = create(Test, 'yck', 26)
console.log(a.name) // 'yck'
console.log(a.age) // 26
a.sayName() // 'yck'

虽然实现代码只有寥寥几行,但是结果很完美

最后

我们通过这篇文章重学了 new 操作符,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
js处理json以及字符串的比较等常用操作
Sep 08 Javascript
防止登录页面出现在frame中js代码
Jul 22 Javascript
JS实现网页表格自动变大缩小的方法
Mar 09 Javascript
JQuery选择器、过滤器大整理
May 26 Javascript
PHP结合jQuery实现红蓝投票功能特效
Jul 22 Javascript
利用CSS3在Angular中实现动画
Jan 15 Javascript
jQuery使用经验小技巧(推荐)
May 31 Javascript
Node学习记录之cluster模块
May 31 Javascript
JS实现新建文件夹功能
Jun 17 Javascript
vue2.0 自定义 饼状图 (Echarts)组件的方法
Mar 02 Javascript
vue单页应用在页面刷新时保留状态数据的方法
Sep 21 Javascript
jquery实现有过渡效果的tab切换
Jul 17 jQuery
jQuery实现的导航条点击后高亮显示功能示例
Mar 04 #jQuery
ES10 特性的完整指南小结
Mar 04 #Javascript
node.js使用express框架进行文件上传详解
Mar 03 #Javascript
微信小程序新手教程之启动页的重要性
Mar 03 #Javascript
微信小程序新手教程之页面打开数量限制
Mar 03 #Javascript
JS实现的冒泡排序,快速排序,插入排序算法示例
Mar 02 #Javascript
JS+php后台实现文件上传功能详解
Mar 02 #Javascript
You might like
安健A254立体声随身听的分析与打磨
2021/03/02 无线电
一个可以找出源代码中所有中文的工具
2006/10/25 PHP
PHP小教程之实现双向链表
2014/06/12 PHP
推荐一款PHP+jQuery制作的列表分页的功能模块
2014/10/14 PHP
PHP指定截取字符串中的中英文或数字字符的实例分享
2016/03/18 PHP
总结PHP中DateTime的常用方法
2016/08/11 PHP
CI框架网页缓存简单用法分析
2018/12/26 PHP
js读写(删除)Cookie实例详解
2013/04/17 Javascript
JS隐藏参数post传值实例
2013/04/18 Javascript
Javascript基础教程之数据类型 (数值 Number)
2015/01/18 Javascript
JavaScript数据类型判定的总结笔记
2015/07/31 Javascript
JS+CSS实现TreeMenu二级树形菜单完整实例
2015/09/18 Javascript
JS实现的在线调色板实例(附demo源码下载)
2016/03/01 Javascript
JS正则表达式学习之贪婪和非贪婪模式实例总结
2016/12/26 Javascript
原生JS实现左右箭头选择日期实例代码
2017/03/14 Javascript
微信小程序实现跟随菜单效果和循环嵌套加载数据
2017/11/21 Javascript
详解vue通过NGINX部署在子目录或者二级目录实践
2018/09/03 Javascript
Angular动态绑定样式及改变UI框架样式的方法小结
2018/09/03 Javascript
解决vue的touchStart事件及click事件冲突问题
2020/07/21 Javascript
python中的yield使用方法
2014/02/11 Python
tensorflow实现softma识别MNIST
2018/03/12 Python
Python 批量合并多个txt文件的实例讲解
2018/05/08 Python
Python实现重建二叉树的三种方法详解
2018/06/23 Python
python列表list保留顺序去重的实例
2018/12/14 Python
在python中按照特定顺序访问字典的方法详解
2018/12/14 Python
Python微信操控itchat的方法
2019/05/31 Python
如何理解python对象
2020/06/21 Python
Boden英国官网:英国知名原创时装品牌
2018/11/06 全球购物
茶叶生产计划书
2014/01/10 职场文书
核心价值观演讲稿
2014/05/13 职场文书
学校教师安全责任书
2014/07/23 职场文书
机械工程及自动化专业求职信
2014/09/03 职场文书
仓库统计员岗位职责
2015/04/14 职场文书
2015年支教教师工作总结
2015/07/22 职场文书
2016教师党员学习心得体会
2016/01/21 职场文书
戴尔Win11系统no bootable devices found解决教程
2022/09/23 数码科技