当前位置: 首页 > 科技观察

是什么让JavaScript有别于其他语言?原型继承!

时间:2023-03-20 15:31:21 科技观察

懂原型继承才算懂JS,原型影响对象的工作方式。面试中经常会问到原型继承,因为这个面试官可以看出你对JS的了解程度。本文主要是帮助大家更好的理解JS中的原型。1.简介JavaScript只有原始类型,null、undefined和object。JS与Java或PHP等语言相反,没有类的概念可以作为创建对象的模板。对象是由多个属性组成的可组合结构:键和值对。例如,下面的对象cat包含2个属性:constcat={sound:'Meow!',legs:4};因为我想在其他对象中重用legs属性,所以让我们将legs属性提取到一个专用对象中constpet={legs:4};constcat={sound:'Meow!'};看起来不错!但我还是希望猫有腿的属性。如何将猫与宠物联系起来?继承可以帮助我们!2.原型对象在JS中,一个对象可以继承另一个对象的属性。继承属性的对象称为原型,或原型。根据定义,我们可以让pet作为cat的原型,继承legs属性。使用对象字面量创建对象时,还可以使用特殊属性__proto__来设置创建对象的原型。constpet={legs:4};constcat={sound:'Meow!',__proto__:pet};cat.legs;//=>4cat对象现在继承原型宠物的腿。现在,我们可以使用值为4的cat.legs。另一方面,声音属性是一个自己的属性,因为它是直接在对象上定义的。JavaScript原型继承的本质:对象可以从其他对象(原型)继承属性。您可能想知道:为什么首先需要继承?继承解决了数据和逻辑重复的问题。通过继承,对象可以共享属性和方法。constpet={legs:4};constcat={sound:'Meow!',__proto__:pet};constdog={sound:'Bark!',__proto__:pet};constpig={sound:'Grunt!',__proto__:pet};cat.legs;//=>4dog.legs;//=>4pig.legs;//=>4cat,dog和pig都复用了属性legs。注意:__proto__已被弃用,但为简单起见,我使用它。在生产环境中,推荐使用Object.create()。2.1自有属性和继承属性如果对象自有属性的名称与继承属性的名称相同,JS会优先使用自有属性。在下面的示例中,鸡对象有自己的属性legs,但也继承了一个同名属性legs:constpet={legs:4};constchicken={sound:'Cluck!',legs:2,__proto__:pet};chicken.legs;//=>2cat对象继承原型宠物的腿。现在您可以使用值为4的属性访问器cat.legs。chicken.legs的值为2。JavaScript在继承时选择自己的属性legs。如果删除自己的属性,JS会选择继承的属性!constpet={legs:4};constchicken={sound:'Cluck!',legs:2,__proto__:pet};chicken.legs;//=>2deletechicken.legs;chicken.legs;//=>43。隐式原型在创建对象时,并没有显式设置原型,JS会给我们创建的对象类型赋一个隐式原型。我们看一下宠物对象constpet={legs:4};pet.toString();//=>`[objectObject]`pet只有一个属性legs,但是我们可以调用方法pet.toString()。这个toString()从哪里来?创建宠物对象后,JS为其分配一个隐式原型对象。pet从这个隐式原型继承toString()方法:Object.getPrototypeOf()方法返回指定对象的原型(内部[[Prototype]]属性的值)。4.原型链我们来创建尾巴对象,让它成为宠物的原型:consttail={hasTail:true};constpet={legs:4,__proto__:tail};constcat={sound:'Meow!',__proto__:pet};cat.hasTail;//=>truecat从它的原型宠物那里继承了腿的属性。但是cat也从其原型的原型尾部继承了hasTail。当访问属性myObject.myProp时,JS会在myObject本身的属性中寻找myProp,对象的原型,原型的prototype等等,直到遇到null为原型。换句话说,JavaScript在原型链中寻找继承的属性。5.但是JavaScript有类。从一开始,JS就只有对象,没有类。你可能一头雾水,你到底在说什么。这可能是因为在ES6中你已经开始使用class关键字。比如你可以写一个Pet类:classPet{legs=4;constructor(sound){this.sound=sound;}}constcat=newPet('Moew!');cat.legs;//=>4catinstanceofPet;//=>true并且cat在实例化类时创建。事实上,JS中的类语法是原型继承的语法糖。上面基于类的代码片段等效于以下内容:constpet={legs:4};functionCreatePet(sound){return{sound,__proto__:pet};}CreatePet.prototype=pet;constcat=CreatePet('Moew!');cat.legs;//=>4catinstanceofCreatePet;//=>trueCreatePet.prototype=宠物赋值对于使catinstanceofCreatePet为真是必要的。6.小结在JavaScript中,对象从其他对象(原型)继承属性,这是原型继承的一个概念。JS在对象的原型中寻找继承的属性,它在原型的原型中寻找继承的属性,等等。虽然原型继承起初可能看起来很笨拙,但一旦我们理解了它,我们就会喜欢它的简单性和可能性。作者:DmitriPavlutin译者:FrontendXiaozhi来源:sitepoint原文:https://dmitripavlutin.com/javascript-prototypal-inheritance/本文转载自微信公众号“大运世界”,可通过以下方式关注二维码。转载本文请联系大千世界公众号。