三分钟带你彻底搞懂`new`关键字

三分钟带你彻底搞懂`new`关键字

七月 08, 2021 本文共计: 461 字 预计阅读时长: 2分钟

一年前的我对于一道面试题,虽然最后知道了答案,但是一直没有机会将它讲的通透。

借此机会,(当一面面试官,面试候选人,但是有好多候选人都不是很清晰),首先,了解这个知识点,你会收获什么?

  • new的实现原理
  • 构造函数的注意事项

看懂本章的前提:你要理解原型链

析题(拆解步骤)

new做了什么事:

  • 绑定 this 的经典操作
  • 拥有自己的构造函数
  • 当返回非引用类型的时候,new返回的是构造函数的prototype.引用类型,返回构造函数的执行结果(这里其实与java的执行结果有所区别)
  • 我们的构造函数名都有一个约定俗成的规范:大驼峰,例如:Person……

直接上代码!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function myNew() {
// 记录函数参数
const _args = Array.from(arguments);

// 拆分构造函数
const constru = [].shift.call(_args);

// 检测构造函数
if (typeof constru !== 'function') {
throw new Error(
`
myNew Error: The constructor should be a function
`
)
}

// 校验函数名
if (constru.name.charAt(0).toUpperCase() !== constru.name.charAt(0)) {
throw new Error(
`
myNew Error: The constructor name's first char should be a Uppercase
`
)
}

// 以构造函数的原型链创建原型对象
const obj = Object.create(constru.prototype);

// 执行构造函数,并且绑定 this 到新建的Obj上,且传入参数
const result = constru.apply(obj, _args);

if (result && (typeof result === 'object' || typeof result === 'function')) {
return result
} else {
return obj
}

}

验证返回值为非引用类型:

1
2
3
4
5
6
7
8

function Test(name, age) {
this.name = name;
}

const a = myNew(Test, "name")

console.log(a)

打印

1
Test { name: 'name' }

验证返回值为引用类型:

1
2
3
4
5
6
7
8
9
10
11
function Test(name, age) {
this.name = name;
return {
age: 14
}
}

const a = myNew(Test, "name")


console.log(a)

打印

1
{ age: 14 }

今天,你学废了吗?