JavaScript构造函数和原型对象

JS中的构造函数

  1. 首字母大写,用来区分一般函数
  2. 创建构造函数后,需要new来实例化
  3. 构造函数内部的this对象,指向即将要生成的实例对象

例子:下面的代码为创建一个Person的构造函数,带有name和age两个形参,所以在new的时候要传入对应的实参,但如果构造函数在实例化时没有用new,而是单纯的让 let p = Person()的话,就是单纯的执行一个Person的函数,但是Person函数并没有返回值,因此会得到undefined

JavaScript构造函数和原型对象
JavaScript构造函数和原型对象

原型对象

每个构造函数都会有原型对象,原型对象默认是空的,用上面的例子来说,Person也有原型对象,查看原型对象的方法是Person.prototype,运行的结果会得到,如下所示:
JavaScript构造函数和原型对象
JavaScript构造函数和原型对象
会发现里面有个constructor的对象里面有我们刚刚创建的Person函数,那这样的话,是不是可以用constructor来找到某个原型对象的构造函数呢,演示如下:
上面的案例直接输出(Person.prototype.constructor);会得到Person函数,证明了我们上面的猜想
JavaScript构造函数和原型对象
那能不能通过Person的实例来找到Person的原型对象呢,回答是:可以的。如果你细心的话会发现上面第二张图,实例出来的p有个__proto__的对象
JavaScript构造函数和原型对象
而且展开这个__proto__,会发现里面也有个constructor的对象里面存着Person函数,打印(p.proto.constructor)出来会发现也能得到Person函数
JavaScript构造函数和原型对象
那这样的话,就产生了几个疑问,既然Person.prototype.constructor是指向Person函数本身,而且实例化出来的p.proto.constructor也能拿到Person函数,那么这两个相等吗?而且Person的原型对象和实例化对象的__proto__相等吗
我们打印一下这个console.log(p.proto.constructor === Person.prototype.constructor)
和这个 console.log(p.proto === Person.prototype);
JavaScript构造函数和原型对象
结果都是true,证明了构造函数的原型对象,和构造函数实例化出来的对象的__proto__是同一个对象,而且他们的constructor会拿到Person的构造函数。

我们用画图的方法来展示一下这些联系,大概就是:
JavaScript构造函数和原型对象