JS 原型与原型链
prototype:在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象
<script>
function Person() {
}
Person.prototype.name = 'abc'
var person = new Person()
console.log(person.name)
</script>
这个例子中,函数的prototype指向了一个对象,而这个对象正是调用构造函数时创建的实例的原型,也就是person的原型
原型的概念:每一个JavaScript对象(JavaScript所有的变量实际上都是对象)(除null以外)创建的时候,就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型中继承属性
JavaScript所有的变量实际上都是对象:如数组的原型是Array.prototype
var a = ['hello', 'world']
function f() {}
console.log(a.__proto__ === Array.prototype) // true
console.log(f.__proto__ === Function.prototype) // true
__proto__:这是每个对象(除null以外)都会有的属性,这个属性会指向该对象的原型
function Person() {
}
var person = new Person()
console.log(person.__proto__ === Person.prototype) //true
console.log(Object.getPrototypeOf(person) === Person.prototype) //true 该方法可以获取对象的原型
constructor:每个原型都有一个constructor属性,指向该关联的构造函数
function Person() {
}
var person = new Person()
console.log(Person === Person.prototype.constructor) //true

console.log(person.constructor === Person) //true
顺便
function Person() {
}
var person = new Person()
console.log(Person === person.constructor) //true
这里在获取person。constructor时,person中并没有constroctor属性,当不能读取到constructor属性时,会从person的原型也就是Person.prototype中读取,即Person === Person.prototype.constructor
当读取实例的属性时,如果找不到,就会查找与对象关联的原型的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止
原型的原型:原型也是一个对象,既然是对象,那么就可以用最原始的方式来创建,如
var obj = new Object()
obj.name = 'abc'
console.log(obj.name)
其实原型对象就是通过Object构造函数生成的:

原型链:一个原型是另一个原型构造函数的实例,如此层层递进,就形成了原型链,下图蓝色的线就是原型链

console.log(Object.prototype.__proto__ === null) //true 即Object.prototype没有原型,意味着查找属性的时候查到Object.prototype就可以停止查找了
JavaScript的继承就是基于原型链的原理,原型里如果找不到就向上一层原型中寻找,直到找到Object.prototype