一.new是什么

定义: new操作符用于创建一个给定构造函数实例对象
简单来说:1.new 能创建一个实例对象; 2.这个对象是给定的构造函数

例子:

function Person(name, age){
    this.name = name;
    this.age = age;
    console.log(this) // Person { name: 'Tom', age: 20 }
}
Person.prototype.sayName = function () {
    console.log(this.name)
}
const person1 = new Person('Tom', 20)
console.log(person1)  // Person {name: "Tom", age: 20}
person1.sayName() // 'Tom'

从这个例子能看出

  • new 通过构造函数 Person 创建出来的实例可以访问到构造函数中的属性
  • new 通过构造函数 Person 创建出来的实例可以访问到构造函数原型链中的属性(即sayName)
  • 构造函数 Person 的 this 指向是 new 通过构造函数 Person 创建出来的实例

二.流程

从上面介绍中,我们可以看到new关键字主要做了以下的工作:

  1. 先创建了一个新的对象newObj
  2. 将新对象newObj与构造函数通过原型链进行连接
  3. 将构造函数的this绑定到新对象newObj
  4. 根据构建函数返回类型作判断,如果是值类型,返回newObj。如果是引用类型,就返回这个引用类型的对象

三.手写流程

了解流程之后,就开始动手写一下

function newFunc(Func,...args) {
    // 1.创建一个新对象
    let newObj = {}
    // 2.将新对象和构造函数通过原型链连接
    newObj.__proto__ = Func.prototype
    // 3.将构造函数的this绑定到新对象上
    const result = Func.apply(newObj,args)
    // 4.根据返回值类型判断,如果是值类型返回newObj,如果是引用类型返回正常引用类型
    return result instanceof Object ? result : newObj   
}

测试一下

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function(){
    console.log(this.name);
}
const person1 = newFunc(Person,'Tom','18')
console.log(person1) // Person { name: 'Tom', age: '18' }
person1.sayName() // Tom

四.额外注意

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName = function(){
    console.log(this.name);
}

Person.getFullName = function() {
    console.log(this.name);;
};

const person1 = new Person('Tom','18')
person1.sayName() // Tom
person1.getFullName() // TypeError: person1.getFullName is not a function

person1.getFullName() 报错, 说明 给构造函数添加属性需要通过原型链, 我们不能像常规对象那样直接给构造函数添加属性,这样添加的属性无法被new的新实例进行使用

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐