这是重学 JS 系列的第一篇文章,写这个系列的初衷也是为了夯实本身的 JS 基础。既然是重学,确定不会从零开始介绍一个知识点,若有遇到不会的内容请自行查找资料。前端
咱们先来经过两个例子来了解 new
的做用git
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'
复制代码
从上面一个例子中咱们能够得出这些结论:github
new
经过构造函数 Test
建立出来的实例能够访问到构造函数中的属性new
经过构造函数 Test
建立出来的实例能够访问到构造函数原型链中的属性,也就是说经过 new
操做符,实例与构造函数经过原型链链接了起来可是当下的构造函数 Test
并无显式 return
任何值(默认返回 undefined
),若是咱们让它返回值会发生什么事情呢?app
function Test(name) {
this.name = name
return 1
}
const t = new Test('yck')
console.log(t.name) // 'yck'
复制代码
虽然上述例子中的构造函数中返回了 1
,可是这个返回值并无任何的用处,获得的结果仍是和以前的例子彻底同样。函数
那么经过这个例子,咱们又能够得出一个结论:ui
试完了返回原始值,咱们再来试试返回对象会发生什么事情吧this
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
仍是依旧正常工做的,可是当返回值为对象时,这个返回值就会被正常的返回出去。spa
那么经过这个例子,咱们再次得出了一个结论:prototype
这两个例子告诉了咱们一点,构造函数尽可能不要返回值。由于返回原始值不会生效,返回对象会致使 new 操做符没有做用。 code
经过以上几个例子,相信你们也大体了解了 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
操做符,若是你还有什么疑问欢迎在评论区与我互动。
我全部的系列文章都会在个人 Github 中最早更新,有兴趣的能够关注下。今年主要会着重写如下三个专栏
最后,以为内容有帮助能够关注下个人公众号 「前端真好玩」咯,会有不少好东西等着你。