new操作符详解
一、new 操作符的作用
在 JS 中,new 操作符用于创建一个给定构造函数的实例对象。就像下面例子这样:
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.say = function () {
console.log('Hello, my name is ' + this.name + ', I am ' + this.age + ' years old.')
}
var person1 = new Person('张三', 20)
console.log(person1) // Person {name: "张三", age: 20}
console.log(person1.name) // 张三
console.log(person1.age) // 20
person1.say() // Hello, my name is 张三, I am 20 years old.
从上面的例子中可以看出,new 操作符创建的实例对象继承了造函数内部的属性,除此之外,new 操作符创建的实例对象也可以访问构造函数原型对象上的属性和方法。
二、new 操作符做了什么
如果给构造函数一个返回值,那么生成的实例对象会是什么呢?
function Person2(name, age) {
this.name = name
this.age = age
return '李四' // 返回基本数据
}
Person2.prototype.say = function () {
console.log('Hello, my name is ' + this.name + ', I am ' + this.age + ' years old.')
}
var person2 = new Person2('张三', 20)
console.log(person2.name) // 李四
console.log(person2.age) // 20
person2.say() // Hello, my name is 张三, I am 20 years old.
function Person3(name, age) {
this.name = name
this.age = age
// 返回对象
return {
name: '李四',
age: 20,
}
}
Person3.prototype.say = function () {
console.log('Hello, my name is ' + this.name + ', I am ' + this.age + ' years old.')
}
const person3 = new Person3('张三', 30)
console.log(person3.name) // 李四
console.log(person3.age) // 20
person3.say() // Uncaught TypeError: person3.say is not a function
从上面两个例子可以看出,如果构造函数返回一个基本类型值,那么这个值会被忽略,返回的是新创建的对象,如果构造函数返回的是一个对象类型值,那么这个值会被正常返回,实例对象就是这个对象类型值。
从上面几个例子我们可以大概推测出 new 操作符做的一些事情:
- 首先,创建一个对象 obj(名字随意取的 ☺)。
- 其次,将构造函数中的 this 绑定到新建的对象 obj 上:Person.apply(obj, [name, age]),这样实例对象才会继承构造函数中的属性。
- 然后,把对象 obj 的原型指向构造函数的 prototype 属性:obj.proto = Person.prototype,这样实例对象才能访问构造函数原型中的属性和方法。
- 最后,根据构建函数返回类型作判断,如果是原始值则被忽略,否则返回新创建的对象 obj。
三、new 操作符的模拟实现
了解了 new 操作符的一些工作原理了,我们写个方法来模拟 new 操作符:
function customNew(Fuc, ...args) {
// 1. 创建一个空对象obj
const obj = {}
// 2. 将构造函数中的this绑定到新建的对象obj上
const result = Fuc.apply(obj, args)
// 3. 将空对象的原型指向构造函数的prototype属性
obj.__proto__ = Fuc.prototype
// 4. 根据构建函数返回类型作判断,如果是原始值则被忽略,如果是返回对象,需要正常处理
return result instanceof Object ? result : obj
}
// 例子验证
function Animal(name, food) {
this.name = name
this.food = food
}
Animal.prototype.eat = function () {
console.log(`${this.name} is eating ${this.food}`)
}
const dog = customNew(Animal, 'dog', 'bones')
console.log(dog) // Animal {name: 'dog', food: 'bones'}
console.log(dog.name) // dog
console.log(dog.food) // bones
console.log(dog instanceof Animal) // true
dog.eat() // dog is eating bones
总结
通过 new 操作符,我们可以轻松的创建对象并为其初始化属性和方法。在实例化的过程中,new 会经历四个重要步骤:创建对象、绑定 this、设置原型和返回对象。理解这些步骤对我们能够掌握 JS 的面向对象编程会有很大的帮助。

浙公网安备 33010602011771号