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 相关文章推荐
JavaScript 嵌套函数指向this对象错误的解决方法
Mar 15 Javascript
jQuery1.6 正式版发布并提供下载
May 05 Javascript
JS实现切换标签页效果实例代码
Nov 01 Javascript
Javascript 普通函数和构造函数的区别
Nov 05 Javascript
js实现HashTable(哈希表)的实例分析
Nov 21 Javascript
socket.io实现在线群聊功能
Apr 07 Javascript
JavaScript队列的应用实例详解【经典数据结构】
Apr 12 Javascript
JS自动生成动态HTML验证码页面
Jun 14 Javascript
iview实现select tree树形下拉框的示例代码
Dec 21 Javascript
JavaScript设计模式之代理模式实例分析
Jan 16 Javascript
vue component 中引入less文件报错 Module build failed
Apr 17 Javascript
微信小程序中网络请求缓存的解决方法
Dec 29 Javascript
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
用mysql触发器自动更新memcache的实现代码
2009/10/11 PHP
PHP从FLV文件获取视频预览图的方法
2015/03/12 PHP
win7系统配置php+Apache+mysql环境的方法
2015/08/21 PHP
php获取flash尺寸详细数据的方法
2016/11/12 PHP
浅谈PHP中pack、unpack的详细用法
2018/03/12 PHP
PHP7 其他语言层面的修改
2021/03/09 PHP
通过MSXML2自动获取QQ个人头像及在线情况(给初学者)
2007/01/22 Javascript
JavaScript 计算图片加载数量的代码
2011/01/01 Javascript
详解Bootstrap glyphicons字体图标
2016/01/04 Javascript
js replace(a,b)之替换字符串中所有指定字符的方法
2016/08/17 Javascript
浅谈jquery设置和获得checkbox选中的问题
2016/08/19 Javascript
微信小程序  http请求封装详解及实例代码
2017/02/15 Javascript
作为老司机使用 React 总结的 11 个经验教训
2017/04/08 Javascript
element-ui多文件上传的实现示例
2019/04/10 Javascript
解决echarts中横坐标值显示不全(自动隐藏)问题
2020/07/20 Javascript
prettier自动格式化去换行的实现代码
2020/08/25 Javascript
Python学习笔记整理3之输入输出、python eval函数
2015/12/14 Python
python机器学习实战之最近邻kNN分类器
2017/12/20 Python
Python使用functools实现注解同步方法
2018/02/06 Python
python OpenCV学习笔记实现二维直方图
2018/02/08 Python
Python图像处理之gif动态图的解析与合成操作详解
2018/12/30 Python
pytorch+lstm实现的pos示例
2020/01/14 Python
浅谈python之自动化运维(Paramiko)
2020/01/31 Python
python函数中将变量名转换成字符串实例
2020/05/11 Python
Python引入多个模块及包的概念过程解析
2020/09/21 Python
pytorch Dataset,DataLoader产生自定义的训练数据案例
2021/03/03 Python
迪卡侬印度官网:购买所有体育用品
2017/06/24 全球购物
集世界奢侈品和设计师品牌的意大利精品买手店:Tessabit
2019/08/17 全球购物
求网格中的黑点分布
2013/11/06 面试题
财务方面个人工作的自我评价
2013/12/28 职场文书
有关打架的检讨书
2014/01/25 职场文书
工程开工庆典邀请函
2014/02/01 职场文书
企业后勤岗位职责
2014/02/28 职场文书
考研英语复习计划
2015/01/19 职场文书
2015年班级工作总结范文
2015/04/03 职场文书
java中重写父类方法加不加@Override详解
2021/06/21 Java/Android