构造函数名一般为大写字母开头,与new运算符一起使用来实例化对象。
// 构造函数
function Person() {
this.name = 'Denise'
}
// 创建对象(实例化)
var p = new Person()
// 打印出来看看
console.log(Person.prototype)
console.log(p)
什么是原型呢?
构造函数在创建的过程中,系统自动创建出来与构造函数相关联的一个空的对象。可以由构造函数.prototype
来访问到。如上述代码,在实例化对象p的过程中,系统就自动创建出了构造函数的原型 Person.prototype
。
每个对象的 __proto__
属性指向自身构造函数的prototype
。如上述代码,对象p的 __proto__
指向 Person.prototype
。
constructor
属性是原型对象Person.prototype
的属性,指向这个原型对象所对应的构造函数,即Person
。
关键在于 __proto__
,那 __proto__
到底是什么呢?
简单来说,每个对象都会有一个 __proto__
属性,当我们访问一个对象的属性时,如果这个对象本身不存在这个属性,那么它就会去 __proto__
里找这个属性,这个 __proto__
又会有自己的 __proto__
,于是就这样一直找下去,这就是所谓的原型链。
在上面这个例子中的p对象的原型链结构图如下:
p -----> Person.prototype (p.__proto__) -------> Object.prototype (p.__proto__.__proto__) ---------> null
那么,new 到底做了什么?
// 构造函数
function Person() {
this.name = 'Denise'
}
// 创建对象(实例化)
var p = new Person()
// 模拟推导过程 -->
var p = {};
p.__proto__ = Person.prototype;
Person.call(p);
1.创建一个空对象 p
2.把这个空对象 p
的属性 __proto__
指向函数 Person
的 prototype
3.将构造函数 Person
的作用域赋给新对象 p
,即 this
指向了 p
4.执行Person
中的代码,为p
添加属性 name
5.返回新对象