序
在segmentfault上看到这样一个主题:
var F=function(){ };object . prototype . a=function(){ };function . prototype . b=function(){ };var f=新F();问:F能得到A和B吗?原理是什么?
乍一看,真的很尴尬。仔细研究,发现还是没有把原型理解透彻,总结了一个,填了个坑~
功能和对象
在解决问题之前,先来说说原型、原型链以及功能与对象的关系,这也是本文的重点。
原型
创建函数时,会自动为其创建一个原型对象,可以通过函数的prototype属性进行访问。
创建构造函数的实例对象,它将包含指向构造函数原型对象的指针(内部属性)。ECMA-262版本5调用这个指针[[原型]]。虽然在脚本中没有访问[[prototype]]的标准方法,但是Firefox、Safari和Chrome在每个对象上都支持一个属性_ _ prototype _ _来访问其构造函数的原型对象。
再说一遍,重要的是构造函数通过prototype属性访问原型对象。实例对象通过[[prototype]]内部属性访问原型对象,浏览器实现实例对象的_ prototype _ attribute访问原型对象。
var F=function(){ };var f=新F();//假设f的原型对象是p,//f . prototype===p;//f . _ _ proto _ _===p;再说一遍。Prototype指的是构造函数和原型对象之间的关系,_ _ prototype _ _指的是实例对象和原型对象之间的关系。
原型链
甲继承乙,乙继承丙.事实上,A的原型对象有一个指向B的原型对象的指针,而B的原型对象有一个指向C的原型对象的指针.请注意,它是原型对象之间的连接。这三个构造器没有关系,所以叫“原型链”~
假设A是A的实例对象,A的原型链由下图中的紫色线表示,橙色线连接构造函数及其原型对象。
从图中可以看出原型链的末端是Object.prototype.__proto__,为空。在寻找A的属性或方法时,首先寻找A本身是否存在,然后沿着原型链进行搜索,直到找到或者最终返回undefined为null。
功能和对象
函数和对象之间的关系有些复杂:
对象是一个构造函数。因为它是函数,所以它是函数的实例对象。函数是构造函数,但函数原型是对象。因为它是一个对象,所以它是对象的实例对象。
所有对象都是对象的实例,所有函数都是函数的实例。
对象是函数的实例,函数原型是对象的实例。
它们之间的关系如下图所示。
可以看到,作为构造函数,Object有一个指向Object.prototype的原型属性,作为实例对象,它有一个Object。__原型_ _指向函数。原型.函数是一个构造函数,它有一个指向Function.prototype的原型属性,而Function是一个函数,所以它有一个Function。__proto__指向Function.prototype,因此该函数。_ _ proto _ _==函数。原型属实。
可以在Chrome控制台下验证,如图。
原标题分析
解决原型链问题最好的方法就是画图。经过前面的分析,这张图应该不是问题,如下~
f的原型链是用蓝线画的,所以f可以访问a,但不能访问b。
不画图的话,乍一看可能觉得F可以访问B,可能会误以为F.prototype和我一样指向Function.prototype,但实际上F.prototype是一个对象而不是函数,所以它的原型对象不会是函数。
所以原型链问题要画出来~
原始标题扩展
在上面的问题中,f只能访问a,不能访问b,但是f可以同时访问a和b,如果问题修改如下,F.b()的结果是什么?为什么呢?可以考虑一下~
var F=function(){ };object . prototype . a=function(){ };function . prototype . b=function(){ console . log(' f . _ _ proto _ _ ')};f . prototype . b=function(){ console . log(' f . prototype ');};摘要
看完这个,你发现这个功能有什么特别的吗?
一般对象只有一个__proto__属性来访问其构造函数的原型对象,但对于函数来说,它既是函数又是对象。
作为一个函数,它天生就有一个指向其原型对象函数名的原型属性。原型。
作为函数的实例对象,它有一个指向函数原型的__proto__属性
一般来说,这两个属性指向两个对象,但是函数的这两个属性指向相同的对象,并且都指向函数原型
对于函数a(),A.prototype中的方法由其实例对象调用,不会自己使用;当作为实例运行时,调用A.__proto__中的方法。也就是说,当它被用作构造函数时,它遵循A.prototype的链,方法和属性被分配给它的实例;当用作对象时,它遵循_ _ proto _ _的链。在不同的场景下,区分其身份不会错。
看完整篇文章,我觉得我说的话比较散漫.请改正我的缺点。至于话题,我真的不知道该怎么称呼。
希望这篇文章能给坚持阅读的你带来一些收获~ _
感谢您对本网站的支持,并继续更新相关资料,帮助您学习这部分知识!