# JS-new操作符

🐴

# new操作符的使用

JavaScript中我们在创建一个新的实例对象时会使用new操作符去创建,我们来看看使用new操作符创建实例的几个例子:

# 第一种使用方式

1.构造函数中没有返回值的实例对象情况

function Person(name,age){
    this.name = name
    this.age = age
}
Person.prototype.getAge = function(){
    console.log(this.age)
}
var XiaoMing = new Person("小明",25)
console.dir(XiaoMing)

上面创建XiaoMing实例,我们可以知道下面几个:

  • 构造函数Person中的this指向了实例化后的对象XiaoMing;
  • 实例化后的对象XiaoMing没有原型prototype,但是有原型链__proto__,原型链指向构造函数Person的原型Person.prototype
  • 并且Person的原型Person.prototype的方法内this指向也实例化后的对象XiaoMing;

# 第二种使用方式

2.构造函数中有返回值,但返回值是基本数据类型的情况

function Person(name,age){
    this.name = name
    this.age = age

    return "hello world!"
}
Person.prototype.getAge = function(){
    console.log(this.age)
}
var XiaoMing = new Person("小明",25)
console.dir(XiaoMing)

这种情况下,虽然构造函数中返回了字符串,但是创建的实例不会有任何变化,它的特点同第一种没有区别。

# 第三种使用方式

3. 构造函数中有返回值,但返回值是对象的情况

function Person(name,age){
    this.name = name
    this.age = age

    return {
        name:'小红',
        age:20
    }
}
Person.prototype.getAge = function(){
    console.log(this.age)
}
var XiaoMing = new Person("小明",25)
console.dir(XiaoMing)

上面创建XiaoMing实例,我们可以知道下面几个:

  • 实例化后的对象XiaoMing 就是返回的对象;
  • 实例化后的原型链指向返回对象的原型;

# new操作符的内部实现

通过上面new操作符的使用特点:我们现在模拟一下使用new实例化构造函数的过程。

我们创建一个simulateNew函数, 该函数接收的第一个参数是构造函数,后面的参数,就是要传入构造函数的参数:

function simulateNew(){
    var obj = {};
    var Fun = [].shift.call(arguments) // 截取并拿到第一个参数
    
     // 执行构造函数,并将this指向obj并传入参数
    var resultFun = Fun.apply(obj,arguments)
    obj.__proto__ = Fun.prototype  //设置obj原型链

    // 返回结果如果是对象就直接返回该对象,否则返回obj对象
    return typeof resultFun == 'object'?resultFun:obj
}

提示

上面我们封装的整个思路是这样的:

  1. 创建一个空对象obj;
  2. 使用[].shift.call截取封装函数的第一个参数,第一个参数为接收的构造函数
  3. 使用apply执行构造函数,并将this指针执行obj, 将剩余的参数传入进入,此时会将构造函数中的属性绑定到obj对象上
  4. obj的原型链指向构造函数的原型
  5. 判断构造函数的返回值是否为对象,如果是则实例化结果为该返回对象,如果不是则为我们创建的obj对象

我们来看看如何使用上面我们封装的仿new操作符的函数:

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

// 调用我们封装的仿`new`操作符函数
var result = simulateNew(Person,"小明",25)

result.name // 小明
result.getAge // 函数
result.__proto__  === Person.prototype  // true

当构造函数中有返回值时,并且返回值是对象时:

function Person (name,age){
    this.name = name
    this.age = age

      return {
            name:'小红',
            age:20
       }
}
Person.prototype.getAge = function(){
    console.log(this.age)
}

// 调用我们封装的仿`new`操作符函数
var result = simulateNew(Person,"小明",25)

result.name // 小红
result.age // 20
result.getAge // undefined

现在我们完成了模拟new操作符在执行时内部的一些操作。

最近更新时间: 7/2/2021, 11:27:27 AM