在去了解原型链之前,一定要先搞清楚两个概念,一个是prototype,一个__proto__。耐心往下看哦
首先什么是prototype?prototype是函数的一个属性,它是一个对象,里面含有两个属性 constructor,__proto__,分别是什么呢??如下图,constructor是一个构造器,它指向自身,而__proto__指向的是对象
记住:一切对象的根源 - Object.prototype
__proto__是对象(除去null)所拥有的一个属性,它指向的构造这个函数的原型对象(prototype),取个栗子
function a(){}
console.log(a.__proto__ === Function.prototype) //true
应该会有人会问,Object的
console.log(Object.prototype.__proto__ === null) //true
怎么解释原型链,其实需要靠大家去理解
写一小段简单的代码,在进行解释
function Person(){}
let p1 = new Persion()
1.每个函数(通常指构造函数,如Person)都有一个属性:prototype
2.prototype是一个对象, 里面有constructor , __proto__ 隐式原型
3.构造函数的原型对象指向当前构造函数 Person.prototype.constructor === Person
4.实例对象的隐式原型指向构造函数的显示原型
p1.__proto__ === Person.prototype
5.在构造函数显示原型中添加的方法,所有的实例对象共享
6.访问属性和方法,是基于原型连进行访问 在当前的实例对象去找--》构造函数的原型 ==》.... =》 Object的原型
光看这几句话会很干,可以看看下面的例子
var F = function(){}
F.prototype.b = function (){
console.log('b()');}
Function.prototype.c = function () {
console.log('c()');}
Object.prototype.a = function () {
console.log('a()')
};
var f = new F();
F.a();
F.b();
F.c();
f.a();
f.b();
f.c();
这道题完全就是和原型相关,如果你能准确的说出答案,那么原型和原型链的理解基本就是明白的了,做这道题的关键需要分 清楚原型链的访问(实例对象直接访问构造函数的显示原型的函数)
画一张图就能很清楚的看出答案,话不多说,看图
看完图之后,可以看出原型链分为两条 - 一条是红色,一条是绿色,原型链上的方法,实例对象都是可以访问的
F.b(),报错,访问F的b方法,应该为F.prototype.b(),记住一句就是实例对象可以直接访问构造函数显示原型的方法
f.c(), 报错,c并不是在f的原型链上面,而是在F的原型链上
第一,万事万物皆对象
console.log(Function.prototype.__proto__ === Object.prototype) //true
console.log(Number.prototype.__proto__ === Object.prototype) //true
然后,js的所有类都是Function的实例,也是Object的派生类,Object对象直接继承Function对象
console.log(Object.constructor === Funciton) //true
console.log(Object instanceof Function) //true
console.log(Function instanceof Object)//true
console.log(Object.__proto__ === Function.__proto__) //true
console.log(Object.__proto__ === Function.prototype); //true
console.log(Function.__proto__ === Function.prototype); //true
也就是说可以理解为对象其实也是由函数构造,Object其实也是个函数,而任何函数都是Function的实例对象(Object.__proto__ === Function.prototype),而函数自己构造了自己(Function.__proto__ === Function.prototype),也来看图理解
但是,敲黑板,不要进入一个误区,如果说一切对象都能访问到Object的prototype里面的方法,像hasOwnProperty,toString,valueOf,toLocaleString等等,那是不是对象都可以访问到在函数原型的方法,答案是,no. 原因又回到了原型链,大家不要进入误区,值得注意的是,原型链的指向,最后指向了Object.prototype而不是Object.__proto__,Object.prototype.__proto__ === null
所以原型链只需要要死死的记住二句话就行了,1.函数的实例对象的隐式原型(__proto__)指向的构造函数的原型对象(prototype),2.所有的最后都指向了对象的显示原型(prototype)
哈哈,终于写完了