js 构造函数 return 非空对象,其实例化的对象在原型上的差异

  • Post author:
  • Post category:其他




一、构造函数

先看下构造函数的定义

ECMAScript 中的构造函数是用于创建特定类型对象的。构造函数也是函数,只是使用

new

操作符调用构造函数会执行如下操作:

(1) 在内存中创建一个

新对象


(2) 这个新对象内部的

[[Prototype]]

特性被赋值为构造函数的

prototype

属性

(3) 构造函数内部的

this

被赋值为这个新对象(即 this 指向新对象)

(4) 执行构造函数内部的代码(给新对象添加属性)

(5) 如果构造函数返回

非空对象

,则返回该对象;否则,返回刚创建的新对象



二、分析

如果不清楚构造函数的定义,就没有必要看这部分了

根据定义,这里将构造函数分为两种:有无返回非空对象。具体区别在哪儿,之前从未细想过



示例1:实例在原型上的不同

function Foo(name) {
  this.name = name
}
function Bar(name) {
  this.age = 27
  return { name }
}
let foo = new Foo('Tom'), bar = new Bar('Tom')

console.log(foo.__proto__ === Foo.prototype) // true
console.log(bar.__proto__ === Bar.prototype) // false

在这里插入图片描述

上图中也可以看出,foo的原型指向Foo的原型,而bar的原型指向Object的原型



示例2

通过这个例子更明显的对比构造函数中的

this



return

的实例

function Foo(name) {
  const _this = this
  this.name = name
  function test(){
    console.log(this, _this)
  }
  return {
    name: 'Tom',
    test
  }
}
let foo = new Foo('Anne')
console.log(foo)
foo.test()

执行

foo.test()



this

打印的是foo,即,实例化时return出来的对象


_this

打印的是实例化过程中创建的新对象,根据定义,该对象原型指向构造函数的原型。相比之下,前者是对象字面量,其原型指向Object的原型

在这里插入图片描述

原型上的区别,意味着,上例中,foo的原型也不指向 Foo的原型,原型的构造函数也并非 Foo。

因此,foo无法访问Foo的原型属性与方法:

function Foo(name) {
  const _this = this
  this.name = name
  function test(){
    return _this
  }
  return {
    name: 'Tom',
    test
  }
}

let foo = new Foo('Anne'), _this = foo.test()

Foo.prototype.age = 18
Foo.prototype.func = function() {
    console.log(this.name, this.age)
}

console.log(!!foo.func, !!_this.func)  // false true
_this.func()                           // Anne 18

针对这点,可以在构造函数内手动将返回的对象原型指向构造函数的原型

如果用不上原型链的话,可以直接忽视这点

function Foo(name) {
  let res = {}
  res.__proto__ = Foo.prototype
  return Object.assign(res, { name })
}
let foo = new Foo('Anne')
Foo.prototype.age = 20
console.log(foo.age) // 20



版权声明:本文为ymzhaobth原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。