当前位置: 首页 > Web前端 > HTML5

JS中原型链和原型的理解

时间:2023-04-05 00:05:50 HTML5

这篇文章主要是学习JavaScript中的难点---原型和原型链自定义一个对象我们学习一门编程语言,我们必须用它来完成一些特定的功能,以及面向对象的语言在这方面做得很好,因为它们符合人类的认知规律。今天我就以JS为例,探讨一下JS与其他面向对象语言的区别------原型和原型链首先,假设你在做一个项目,想要创建一个新的对象,这不在标准库中。那只能用构造函数构造一个函数Person(){//constructor}上面的Person是一个构造函数,可以用来生成小明、小红等人的实例。varperson=newPerson()//构造一个对象person.name='xiaoming'console.log(person.name)//'xiaoming'的原型在哪里?要了解原型,首先要了解原型属性。代码Person.prototype.name='god'varperson2=newPerson()console.log(person2.name)//person2的名字是什么???从上面三行代码,猜猜person2的名字是什么,是的,godperson2并没有自己指定的名字,但是Person构造函数的原型绑定了名字,所以Person构造函数构造的实例对象有默认一个。上帝的名字。而这个原型属性只存在于构造函数上,也就是说原型是构造函数的一个属性!!!这个原型指向哪里?那个地方就是调用构造函数生成的对象实例的原型,存放的就是这个原型的地址。以上就是构造函数和原型的关系。构造函数内部的原型属性指向实例对象原型的地址。原型存储所有实例化对象的公共属性,例如本例中的名称。上图红框是Person实例的原型。如果不直观,直接看Array实例的原型。红色框内就是大家熟悉的数组方法。它们都放在数组的公共属性中。在上面两个原型图中,我们发现它们有一些共同点。它们都有一个熟悉的constructor属性,后面再研究。现在,我们已经知道了构造函数和原型的关系,那么personperson2的实例对象和原型是什么关系呢?__proto__属性每一个构造的实例对象内部都有一个__proto__属性,它指向实例原型,存放原型的地址。person.__proto__===Person.prototypetrue__proto__是对象的一个??属性,是浏览器强制ECMAScript添加的规范。以上是构造函数、实例、实例原型的关系,但是方向是单向的。怎么可能循环呢?原型可以指向构造函数或实例吗?构造函数还记得我们上面发现不同的原型有一个共同的属性。构造函数,构造函数、实例、实例原型之间关系方向的关键,可以在这里循环。我们一直叫constructor,constructor,为什么这么叫,没错,就是这个原型中的constructor属性。但是原型不能指向实例,只能通过构造函数属性Person===Person.prototype.constructortrue指向构造函数上面就是经典的铁三角。由上面的知识,我们可以得到一个小公式对象.__proto__===constructor.prototype而Person的构造函数也是一个对象,那么Person.__proto__===???上面问号填什么,我们按照公式填空,应该是Constructor.prototype,Person构造函数的构造函数是谁?没错,就是Function。Person.__proto__===Function.prototypetrue在控制台中验证它确实如此。所以之前的一些疑惑也解决了Array.__proto__===Function.prototypetrueString.__proto__===Function.prototypetrue那么问题又来了,constructor.prototype也是一个对象,它指向谁既然是对象,那么就是有一个__proto__属性Person.prototype.__proto__===???问号里填什么,原型是谁构造的,我们想到了万物之根--------Object原型的原型在控制台验证如下Person.prototype.__proto__===Object.prototypetrueArray.prototype.__proto__===Object.prototypetrueString.prototype.__proto__===Object.prototypetrueObject.prototypetrue推导出来了,我们来看看所有对象的祖先Prototype吧Object.prototype.__proto__===nulltrue特殊函数我们已经看到了Function构造函数可以构造除普通构造函数之外的所有函数。那么他本身也是一个函数,所以也是通过Function构造器来构造的。所以从总结的公式中,我们可以知道Function.__proto__===Function.prototypeand,下面很重要,容易出错Function.prototype===Object.__proto__//哈哈,这个老生常谈了,我给你倒着写,容易造成误解:对象也是构造函数,属于对象。Object构造函数也是由Function构造的,所以结果为真。完整总结当你创建一个新的构造函数时,创建一个函数实例,然后“函数实例.__proto__===这个构造函数.prototype”所有函数都是从Function构造的,然后“其他函数构造.__proto__===Function.prototype”所有构造函数的原型对象都是从Object构造出来的,那么“所有constructors.prototype.__proto__===Object.prototype』instanceof运算符的本质首先有几个问题ObjectinstanceofFunctionFunctioninstanceofObjectFunctioninstanceofFunctionObjectinstanceofObject你能不假思索的说出来,大声告诉我答案是什么,没错,都是真的。虽然instanceof操作符是我们的老朋友,但是后面怎么判断呢?规范是这样写的。是否constructor.prototype存在于参数对象的原型链上ForObjectinstanceofFunction,Object.__proto__===Function.prototype为真,resolveForFunctioninstanceofObject,Function.__proto__.__proto__===Function.prototype.__proto__===Object.原型是真的,已解决。ForFunctioninstanceofFunction,Function.__proto__===Function.prototype为真,求解ForObjectinstanceofObject,Object.__proto__.__proto__===Function.prototype.__proto__===Object.prototype为真,求解只要上面的推导,如果你写错了或者根本不会写任何链接(我今天之前就在胡闹,运气好,答对了),那说明你没有真正理解原型链,还是面试中问稍微变形的问题容易出错。上面各种原型的改造,难点在于FunctionObject的构造器也是一个对象,原型对象等所有对象都是从这四点构造出来的。而且,不同的看待问题的角度对事实的认知有很大的影响。比如你把ObjectFunction看成构造函数或者对象,结果就不一样了。不同的场合,不同的角度去理解它们,事物有两个方面。大概是背了很多年雷同,巴拉巴拉的一堆哲理。各种原型的分析过程让我想起了被数学支配的恐惧。逻辑要合理,一步一个脚印,剥开本质才能看到本质。大概是这么多年应试教育在脑海里留下的深刻烙印吧。JS越来越有意思了,感觉应该快点入门了。原型链嘿,它在哪里?原型链如上。对于每个对象,都有一个沿着__prto__属性的链。搜索并搜索,直到找到Object.prototype。感谢Saeyu和Ruoyu的文章。