这可能是一个常看常新的问题,因为。。我总是记不住。所以来写一篇,顺便加深一下自己的记忆。
先说prototype。
每创建一个新函数,都会创建一个prototype(原型)属性,例如:
function Person() {}
var person1 = new Person();
var person2 = new Person();
如上图所示,person1和person2内部的指针都指向了Person.prototype,而不是Person本身。
这个(prototype)属性是一个指针,指向函数的原型对象。所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性指向prototype属性所在函数的指针。如上述例子中,Person.prototype.constructor 就指向Person。
JS中提供了isPrototypeOf()和getPrototypeOf()来进行原型的判断和获取原型。大部分浏览器都支持这种写法。IE9以下是不提供的。
需注意的是,当代码读取某个对象的属性时,它会先对该对象进行搜索,搜索不到的时候会去它指向的原型对象去搜索。如person1.name,在没有定义的情况下就会去Person.prototype里面寻找,从而返回“Nicholas”。
接下来谈一下原型链。
原型链的基本思想,是利用原型让一个引用类型继承另一个引用类型的属性和方法。也就是说,函数A()有一个原型对象A.prototype,A.prototype包含一个指向A的指针,这时候实例B=new A(), B就包含了一个指向A.prototype的指针。那么如果这时让A.prototype = new C()呢?这时候A.prototype就包含了一个指向C的指针,如果C.prototype 又等于new D()......就这样层层递进,就构成了实例与原型的链条。以上就是原型链的基本概念。
要想确定原型和实例之间的关系,
第一种方法是instanceof操作符。例如: B instanceof Object; B instanceof A; B instanceof C; 结果都为true
第二种方法是isPrototypeOf()。例如: A.prototype.isPropotypeOf(B); 结果也为true。
原型链最大的弊端就是引用类型的属性会被所有实例共享,实践中很少单独使用原型链。但是这些原理还是需要弄明白的,以上就是本次总结的全部知识点啦,下次再聊~
欢迎来留言
参考:《JavaScript高级程序设计》(第3版)