详解 Javascript 中 new 操作符的运行机制

在讲 Javascript 中 new 操作符的机制之前,首先需要说明的一点是:Javascript 中 new 操作符的机制和传统的面向对象语言的 new 机制完全不同,所以千万不要把两者联系到一起来理解。

好了,记住上面一点后,我们来说一下 new 操作符的用法,看下面的代码:

let obj = new FunctionName()

new 操作符使用起来很简单,只要在 new 操作符的后面加上已经定义了的函数名,再加上括号即可。该操作符的返回值是一个对象字面量。其内部运行的机制可分为以下四个步骤:

  1. 创建一个全新的对象。
  2. 将这个对象的原型链(__proto__)指向函数的 .prototype。
  3. 将这个对象绑定到函数中的 this,然后执行函数,函数内部可以借助 this 给这个对象添加属性。
  4. 如果这个函数没有返回其他对象的话,new 操作符就会将上面步骤创建的对象返回出去。但如果该函数最后返回了一个其他对象的话,new 操作符就会把这个函数返回的对象返回出去。

例如,我们想创建一个 "人" 的对象。

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

Person.prototype = {
  speak() {
    console.log(`我的名字叫${this.name},今年${this.age}岁了,身高是${this.height}。`)
  }
}

let p = new Person({
  name: 'tom',
  age: 18,
  height: 180
})


console.log(p)    // { name: 'tom', age: 18, height: 180 }
p.speak()    // 我的名字叫tom,今年18岁了,身高是180。

上面代码中的对象 p 就是 new 操作符的返回值对象,又因为 Person 函数最后没有返回其他的对象,所以 p 就是上面四个步骤中的第一个所创建的那个对象。

因为这个对象的原型链指向 Person.prototype,所以 p 能够获取并执行 speak 方法。

因为这个对象被绑定到了函数中的 this,所以 p 的值是  { name: 'tom', age: 18, height: 180 }。


下面展示 Person 函数返回其他对象的情况,看下面的代码:

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

  let otherObj = {
    foo: '111',
    bar: '222'
  }

  return otherObj
}

Person.prototype = {
  speak() {
    console.log(`我的名字叫${this.name},今年${this.age}岁了,身高是${this.height}。`)
  }
}

let p = new Person({
  name: 'tom',
  age: 18,
  height: 180
})

console.log(p)
p.speak()

这段代码的执行结果如下图所示:

因为 Person 函数最后返回了一个其他的对象(otherObj),所以 new 操作符将 Person 函数返回的这个对象返回出去,所以 p 指向 otherObj。

所以 console.log(p) 的结果是 { foo: '111', bar: '222' }。

又因为这个返回对象的原型链并没有指向 Person.prototype,所以 p.speak 是 undefined,因此报错:p.speak is not a function。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值