摘要:原型对象是由创建的,因此原型对象的构造函数是构造函数也可以是称为对象,原型对象也就继承了其生父构造函数中的数据,也同时继承了原型对象的数据。当然这条原型链中的数据,会被还是还是这类构造函数继承,但是不会被这些继承,他们不处于同一个链条上。
js中,Function的本质是什么?
Object的本质又是什么?
js中有几条原型链?
javascript的语言基于原型链,而实际上js的有两条原型链。开发者主要用到的是图中的红色原型链,如给Array.prototype.xxx=yyy,那么就可以[...].xxx,数组实例对象就继承了其构造函数原型对象中的数据,当然实践一般不会给修改Array这类构造函数的原型对象,最多的就是自定义构造函数,然后给自定义的构造函数定义原型对象,那么这个构造函数的所有实例对象也就都继承了原型对象中的数据。这就是图中红色原型链的所表示的。
那么Array.prototype和自定义构造函数function f(){}的prototype的原型对象是从哪里来的,是谁创造了它?
诸如Array.prototype.xxx=yyy,这实际上就是引用了Array的原型对象prototype而已,也就是它的原型对象就已经存在了,然后才让其能够被引用到。
包括Array.prototype,还是String.prototype,还是Object.prototype,还是Function.prototype,还是自定义构造函数function f(){}的prototype,它们都不是开发者创建的,而是Function构造函数在创建其他构造函数时,用Object()创建的。
可以说Function构造函数是javascript世界中的万物之主,像盘古开天辟地创建了javascript的语言世界和运行机制。而OBject的本质就是用于创建原型对象。
Function构造函数内部有一个this.prototype=new Object(),当Function造物时,就同时通过这句this.prototype=new Object(),给这个物赋予了灵魂。而Object在javascript中的本质也就在于此,作为Function手中的魂灯,赋予其创建的物体灵魂,也就是给予它原型对象,让它能够通过原型对象,能够从上面继承和吸收能量。
Function构造函数,创建了Array构造函数,同时通过new Object()给其创建了prototype对象,因此有Array.prototype。然后[1,2,3]就是由Array构造函数创建,因此[1,2,3]数组实例对象,继承了Array构造函数中的数据,同时继承了Array.prototype中的数据。
Array.prototype原型对象是由this.prototyoe=new Object()创建的,因此Array.prototype原型对象的构造函数是Object构造函数(也可以是称为对象),Array.prototype原型对象也就继承了其生父Object构造函数中的数据,也同时继承了Object.prototype原型对象的数据。
因此,你可以看到,toString()这个方法追根溯源,实际上是Object.prototype.toString,在Function创建Array的时候,Object就跟着创建了Array.prototype,它就继承了Object和Object.prototype中的数据,[1,2,3]数组对象由Array创建,因此[1,2,3]也就继承了Array、Array.prototype、Object、Object.prototype中的数据,因此最终才可以调用[1,2,3].toString()。
对于String、Boolean等构造函数,还是自定义构造函数function f(){...}也都是这样。
function f(){...},看上去是你写了这个普通的构造函数,实际上这个普通的函数是Function创建的,你写的这个f函数,由于是Function()实例化出来的(也就是函数的f的构造函数就是Function),那么普通函数f作为Function构造函数的实例对象,那么普通函数f也就会继承Function构造函数和Function.prototype中的数据。
说来诡异的是,也是Function自己创建了自己,正是在在创建自己的时候,通过this.prototype=new Object()给自己也创建了原型对象,就是图中蓝色的原型对象,这个原型对象由于是new Object实例化的,因此这个蓝色的原型对象,也就继承了Object和Object.prototype原型对象中的数据,这样说来,Object的原型对象是原型链条中的最顶层的一个对象,然后原型链往下揪分裂成了两条。
Function.prototype原型对象虽然继承了Object.prototype中的数据,但是它自己还扩展了自己专有的属性和方法,分别是name、length、call()、apply()、bind()这五个,然后由于普通函数f就是由Funciton创建出来的,因此这个普通函数也就继承了Function和Function.prototype中的数据,因此你才可以使用f.apply()还是f.bind(this),也因此才可以使用Array.apply(),这就是图中的第二条蓝色的原型链。当然这条原型链中的数据,会被Array还是String还是Boolean这类构造函数继承,但是不会被[1,2,3]这些继承,他们不处于同一个链条上。
虽然Function创建了它自己,也创建了Object,但到底它是先创建自己还是先创建Object就无从得知了。如果Function先创建了自己,那么在它创建自己的时候,还在使用this.prototype=new Object()给自己创建原型对象时,这个Object又是哪里来的,难道Object就已经先存在了?如果Object先于Function存在了,但Funciton都还没有存在,它怎么去创建Object?这到底是鸡生蛋还是蛋生鸡无从得知,这也反映了javascript语言底层机制就是混乱的。
也许这一切都很绕,但是只有理解了Function与Object,才能更清晰高屋建瓴的理解原本繁芜繁杂和混乱的javascript。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/83923.html
摘要:相当于在用原型继承编写复杂代码前理解原型继承模型十分重要。同时,还要清楚代码中原型链的长度,并在必要时结束原型链,以避免可能存在的性能问题。 js是一门动态语言,js没有类的概念,ES6 新增了class 关键字,但只是语法糖,JavaScript 仍旧是基于原型。 至于继承,js的继承与java这种传统的继承不一样.js是基于原型链的继承. 在javascript里面,每个对象都有一...
摘要:写在前面如果说是一本武学典籍,那么原型链就是九阳神功。那么,如何修炼好中的九阳神功呢真正的功法大成的技术是从底层上去理解,那种工程师和码农的区别就在于对底层的理解,当你写完一行代码,或者你遇见一个解决的速度取决于你对底层的理解。 写在前面 如果说JavaScript是一本武学典籍,那么原型链就是九阳神功。在金庸的武侠小说里面,对九阳神功是这样描述的:练成「九阳神功」后,会易筋洗髓;生出...
摘要:写在前面如果说是一本武学典籍,那么原型链就是九阳神功。那么,如何修炼好中的九阳神功呢真正的功法大成的技术是从底层上去理解,那种工程师和码农的区别就在于对底层的理解,当你写完一行代码,或者你遇见一个解决的速度取决于你对底层的理解。 写在前面 如果说JavaScript是一本武学典籍,那么原型链就是九阳神功。在金庸的武侠小说里面,对九阳神功是这样描述的:练成「九阳神功」后,会易筋洗髓;生出...
摘要:写在前面如果说是一本武学典籍,那么原型链就是九阳神功。那么,如何修炼好中的九阳神功呢真正的功法大成的技术是从底层上去理解,那种工程师和码农的区别就在于对底层的理解,当你写完一行代码,或者你遇见一个解决的速度取决于你对底层的理解。 写在前面 如果说JavaScript是一本武学典籍,那么原型链就是九阳神功。在金庸的武侠小说里面,对九阳神功是这样描述的:练成「九阳神功」后,会易筋洗髓;生出...
阅读 954·2021-11-17 09:33
阅读 414·2019-08-30 11:16
阅读 2467·2019-08-29 16:05
阅读 3350·2019-08-29 15:28
阅读 1392·2019-08-29 11:29
阅读 1947·2019-08-26 13:51
阅读 3384·2019-08-26 11:55
阅读 1203·2019-08-26 11:31