原型,原型链学习笔记
我们先使用构造函数创建一个对象
function Person() {
}
var person1 = new Person()
person1.name = 'dada'
console.log(person1.name);
在这个列子中Person 就是一个构造函数 person1 是Person构造函数的一个实例对象。接下来进入正题:
pertotype
每一个构造函数都有pertotype属性,就是我们经常在例子里看到的。列入:
function Person() {
}
Person.prototype.name = 'Kevin';
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) // Kevin
console.log(person2.name) // Kevin
那么这个函数的prototype到底指向的是什么?是这个构造函数的原型吗?
其实:prototype指向的是一个对象,这个对象就是调用该构造函数而创建出来的实列的原型,也就是这个例子中的person1和person2的原型
我来用一张图来表示构造函数和实列原型直接的关系
那么我们该如何表示实列与实列原型之间的关系呢(也就是person1,person2 和Person之间的关系)?需要引入第二个属性
__proto__
这是每一个实列对象(除了null)都有的一个属性 叫__proto__ ,指向该对象的原型 以下代码可以体现出这一点
function Person() {
}
var person1 = new Person()
console.log( person1.__proto__ === Person.prototype); //true
于是便有了一下关系图
既然实列对象和构造函数都可以指向原型,那么原型是否是属性可以指会构造函数或者实列对象呢?
constructor
指向实列对象是没有,但是指向构造函数是有的 就是constructor属性,看一下代码
function Person() {
}
var person1 = new Person()
console.log( Person.prototype.constructor === Person); // true
那么又可以跟新图片:
以上就是构造函数、实例原型、和实例之间的关系
实列与原型
当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。例如:
function Person() {
}
Person.prototype.name = 'dada'
var person = new Person()
person.name = 'haha'
console.log(person.name); //dada
delete person.name
console.log(person.name); //haha
在这个例子中 给Person构造函数的prototype和person实列对象都添加了一个name属性
当第一次打印person.name()是,自然会打印 ‘dada’
当我么删除实列对象上的name属性 为什么又会打印 ‘haha’呢? 因为实列对象会首先在自己身上查找name属性,如果找到,就直接打印,如果没有找到,就会person的原型里面找name属性,这个例子在person的原型里面找到了name属性,于是打印‘haha’,但是如果没有找到呢?
原型的原型
在前面,我们已经讲了原型也是一个对象,既然是对象,我们就可以用最原始的方式创建它,那就是:
var obj = new Object();
obj.name = 'Kevin'
console.log(obj.name) // Kevin
然后就又可以更新关系图:
最后结合一下图学习可以理解的更加透彻:
以上内容参考网址: github.com/mqyqingfeng…