当前位置: 首页 > 后端技术 > Node.js

javascript原型详解

时间:2023-04-03 17:52:48 Node.js

javascript原型详解Tag:javascriptPrototype在javascript中是一个比较难理解的概念。javascript的权威指南在原型的章节中也花费了大量的篇幅。也许你已经看过权威的javascript指南,或者你已经看过第N篇文章。不过这篇文章的目的是看完之后用。几分钟梳理知识脉络。什么是原型?在javascript中,原型就是一个对象,通过原型可以实现属性的继承。letpersonBase=newObject()personBase.gender='male'letanimal={eyeNumber:2}lettime=function(){lettimeType='seconds'}上面创建的三个对象可以作为任何函数的原型.functionPerson(age){this.age=age}Person.prototype=personBaselettom=newPerson(18)console.log(tom.age)//18console.log(tom.gender)//'male'personBase是Person原型。所以构造函数Person从personBase继承了gender属性的原型:每一个JavaScript对象(假定为A,null除外)在创建时都会与另一个对象相关联。这个对象就是我们所说的原型,而每个对象的属性都是从原型“继承”而来的。A,可能是大多数编码场景中的一个函数。函数默认继承自Function,即Function默认是所有函数的原型。当我们通过原型属性向函数添加原型对象时,原型对象将被添加到原型链的近端。当然A也可以是其他数据类型(Number、String、Array、Boolean),比如Number类型。当我们通过字面量方式(vara=1)初始化变量时,相当于通过构造函数(vara=newNumber(1))实例化一个变量,即字面量方式创建的变量也是一个实例数量。所以我们可以通过Number的prototype属性来实现属性和方法的继承。(当然不推荐这样做)构造器、实例、原型的关系理解这三者的关系的关键是理解原型、__proto__、构造器之间的联系:attribute——原型函数属性,指向原型__proto__instance属性,指向原型构造函数prototype属性,指向构造函数在JavaScript中,每个函数都有一个原型属性,当一个函数作为构造函数创建一个实例时,该函数的原型属性的值将是assignedasaprototype给所有的对象实例(设置实例的__proto__属性),即所有实例的原型都引用构造函数的prototype属性。同时,原型对象包含一个“constructor”属性,它对应于创建所有指向原型的实例的构造函数(说的有点啰嗦,就是constructor属性指向构造函数)。这三者的关系可以用下面的例子图表示:所以构造函数通过prototype属性指向自己的prototype。构造函数的实例创建后,通过__proto__属性指向构造函数的原型对象,即实例函数也指向原型。构造函数和实例都通过属性指向原型。代码示例:functionPerson(){}letmanPerson=newPerson()manPerson.__proto__===Person.prototype//truePerson.prototype.constructor===Person//truemanPerson.constructor===Person.prototype。constructor//truemanPerson是构造函数Person的一个实例。manPerson的__proto__属性等于Person的prototype属性保存的值,即指向同一个对象原型。Person的原型(Person.prototype)通过constructor属性指向构造函数Person,即Person和他的原型的constructor属性实现互引用实例等于原型的constructor属性。这里实例的constructor属性是继承自原型的constructor属性。相反,原型和构造函数没有对实例的引用,因为构造函数将有N个实例。JavaScript通过实例的__proto__属性访问公共原型。所有函数都是Function构造函数的实例,函数也是对象。同时,创建函数实例的字面方式相当于创建构造函数。letfoo=newFunction()fooinstanceofFunction//truetooinstanceofFunction//truefoo.__proto__===too.__proto__//truefoo.__proto__===Function.prototype//truefoo是Function的一个实例所以too和foo都是Function的实例,它们的_proto__指向的是Function构造函数的原型。通过上面示例代码的分析,主要涉及prototype、__proto__、constructor这三个属性之间的关系。我们再梳理一下:对于所有的对象,都有一个__proto__属性,对应对象的原型。对于函数对象,除了__proto__属性外,还有一个原型属性。当一个函数作为构造函数来创建一个实例时,该函数的prototype属性的值会作为原型赋值给所有的对象实例(即实例的__proto__属性被设置)。所有的原型对象都有一个constructor属性,对应于创建所有指向原型的实例。ConstructorFunction对象和原型对象通过prototype和constructor属性相互关联,所以上面的关系图其实可以理解为:题外话:Function.prototype===Function.__proto__哪个先来,鸡还是那个蛋?作为构造函数的Function如何等同于作为实例对象的Function原型?在JavaScript中,Function构造函数本身是Function类型的实例吗?Function构造函数的prototype属性和__proto__属性都指向同一个原型。难道说Function对象就是Function构造函数创建的实例吗?相关问题Function是JavaScript中的基本类型吗?在JavaScript中,Function构造函数本身是Function类型的实例吗?没有必要深究这些问题。构造函数原型的constructor属性指向对应的构造函数Person(){}console.log(Person===Person.prototype.constructor);//真正的原型链理解了原型的概念之后,原型链就更容易理解了。因为每个对象和原型都有一个原型,对象的原型指向对象的父对象,父对象的原型指向父对象的父对象。原型链由原型层连接而成。.JavaScript对象通过__proto__链接到原型对象。原型链的概念并不难理解。在访问对象的属性时,不仅在对象上查找,还会查找对象的原型,对象原型的原型,依次向上查找,直到找到名称匹配的A属性or到达原型链的末尾,如果找到则返回该属性的值,否则返回undefind(原型链的末尾为null)。对于javascript中各种数据类型的原型之间的关系,可以参考下图来理解: