概述
在JavaScript中,我们创建对象用的是 new Xxx() 的办法,而在java这样的典型的面向对象语言中,也是通过同样的写法创建对象。虽然二者写法类似,但是理解完全不同。
通常,java的面向对象可以简单理解为,做月饼。我有一个月饼模子,把材料放里面,就可以得到一个月饼。是一种基于模型创建对象的模式。
JavaScript的面向对象可以理解,克隆技术。已经存在一只羊,我可以克隆个一模一样的出来,然后再加入新的改造。是一种基于对象创建对象的模式。
证据就在于JavaScript中new出来的对象和构造函数毫无关系。
结论:它的[[prototype]] (也就是 __proto__)属性指向的是原型对象,而不是构造函数,构造函数在创建对象的过程中,仅仅只是个负责搬运和克隆的工具人。
详解
如果把JavaScript的面向对象比喻成一场戏,那有这么三个重要角色:
- 被创建出来的对象
- 构造函数
- 原型对象
function Person() {
this.name = name;
}
const jack = new Person('jack');
const lily = new Person('lily');
新创造出来的对象 => jack,lily
构造函数 => Person
原型对象 => Person.prototype
这三者之间的关系如下:
1.新创造出来的对象 通过 __proto__ 属性指向 【原型对象】。
// 原型对象
const prototypeObject = Person.prototype
// 新创造出来的对象 的 __proto__ 属性指向原型对象
jack.__proto__ === prototypeObject // true
2.构造函数在这个过程中,负责牵线搭桥。构造函数要通过prototype属性跟目标的【原型对象】绑定关系,同时 原型对象 也通过constructor属性跟【构造函数】绑定成双向链表。
// 构造函数 通过prototype绑定原型对象
Person.prototype === prototypeObject // true
// 原型对象通过constructor绑定构造函数
prototypeObject.constructor === Person // true
完整代码
function Person() {
this.name = name;
}
var jack = new Person('jack');
var lily = new Person('lily');
// 原型对象
const prototypeObject = Person.prototype
// 新创造出来的对象 的 __proto__ 属性指向原型对象
jack.__proto__ === prototypeObject
// 构造函数 通过prototype绑定原型对象
Person.prototype === prototypeObject
// 原型对象通过constructor绑定构造函数
prototypeObject.constructor === Person
REFERENCE
@wx:qq981145483