new的作用

new 的作用

1
2
3
4
5
6
7
8
9
10
11
function Test(name){
this.name = name
}

Test.prototype.sayName = function (){
console.log('xxxxx',this.name)
}

const t = new Test('Jeffrey')
console.log(t.name) // 'Jeffrey'
t.sayName() // 'Jeffrey'

从代码中我们可以知道,new的作用

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

构造函数返回原始值

1
2
3
4
5
6
function Test(name) {
this.name = name
return 1
}
const t = new Test('Jeffrey')
console.log(t.name) // 'Jeffrey'

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

构造函数返回对象

1
2
3
4
5
6
7
8
function Test(name) {
this.name = name
console.log(this) // Test { name: 'Jeffrey' }
return { age: 26 }
}
const t = new Test('Jeffrey')
console.log(t) // { age: 26 }
console.log(t.name) // 'undefined'

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

自己实现 new 操作符

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

  • new 操作符会返回一个对象,所以我们需要在内部创建一个对象
  • 这个对象,也就是构造函数中的 this,可以访问到挂载在 this 上的任意属性
  • 这个对象可以访问到构造函数原型上的属性,所以需要将对象与构造函数链接起来
  • 返回原始值需要忽略,返回对象需要正常处理
1
2
3
4
5
6
7
8
9
10
11
//首先函数接受不定量的参数,第一个参数为构造函数,接下来的参数被构造函数使用
function create(Con, ...args) {
//然后内部创建一个空对象 obj
let obj = {}
//因为 obj 对象需要访问到构造函数原型链上的属性,所以我们通过 setPrototypeOf 将两者联系起来。这段代码等同于 obj.__proto__ = Con.prototype
Object.setPrototypeOf(obj, Con.prototype)
//将 obj 绑定到构造函数上,并且传入剩余的参数
let result = Con.apply(obj, args)
//判断构造函数返回值是否为对象,如果为对象就使用构造函数返回的值,否则使用 obj,这样就实现了忽略构造函数返回的原始值
return result instanceof Object ? result : obj
}

测试

1
2
3
4
5
6
7
8
9
10
11
function Test(name, age) {
this.name = name
this.age = age
}
Test.prototype.sayName = function () {
console.log(this.name)
}
const a = create(Test, 'Jeffrey', 26)
console.log(a.name) // 'Jeffrey'
console.log(a.age) // 26
a.sayName() // 'Jeffrey'

参考链接[‘https://juejin.im/post/5c7b963ae51d453eb173896e']

参考链接[‘https://juejin.im/post/5bde7c926fb9a049f66b8b52']