Constructor 构造函数
首先先写一个构造函数 Person,构造函数一般为了区别普通函数要求首字母大写:
function Person(){
}
prototype 原型
原型指的就是一个对象,实例“继承”那个对象的属性。在原型上定义的属性,通过“继承”,实例也拥有了这个属性。“继承”这个行为是在 new 操作符内部实现的。
先不说实例,原型与构造函数的关系就是,构造函数(Person)内部有一个名为 prototype 的属性,通过这个属性就能访问到原型:
instance 实例
function Person(){
}
let person =new Person()// new出来的实例对象 instance
function Person(){
}
let person =new Person()
//在原型上定义属性,可以被new出来的实例对象继承
Person.prototype.name="张三"
console.log(person.name);//张三
proto 隐式原型
实例通过 proto 访问到原型,所以如果是实例,那么就可以通过这个属性直接访问到原型:
所以这两者是等价的:
function Person(){
}
let person =new Person()
//在原型上定义属性,可以被new出来的实例对象继承
Person.prototype.name="张三"
console.log(person.name);//张三
console.log(person.__proto__ === Person.prototype);//true
constructor 构造函数
既然构造函数通过 prototype 来访问到原型,那么原型也应该能够通过某种途径访问到构造函数,这就是 constructor:
function Person(){
}
let person =new Person()
//在原型上定义属性,可以被new出来的实例对象继承
Person.prototype.name="张三"
console.log(person.name);//张三
console.log(person.__proto__ === Person.prototype);//true
//constructor 构造函数
console.log(Person.prototype.constructor==Person);//true
因此两者的关系应该是这样:
原型链
原型同样也可以通过 proto 访问到原型的原型,比方说这里有个构造函数 Person 然后“继承”前者的有一个构造函数 People,然后 new People 得到实例 p
当访问 p 中的一个非自有属性的时候,就会通过 proto 作为桥梁连接起来的一系列原型、原型的原型、原型的原型的原型直到 Object 构造函数为止。
这个搜索的过程形成的链状关系就是原型链