原型链原型链是一种机制,意思是每一个JavaScript对象,包括原型对象,都有一个内置的[[proto]]属性指向函数的原型对象创建它的对象。那就是原型属性。原型链的存在主要是为了实现对象的继承。函数是对象。js分为函数对象和普通对象。每个对象都有一个__proto__属性,但只有函数对象有一个原型属性。RegExp、Date、Boolean、Number、String__proto__JavaScript在创建对象时都会有一个[[proto]]内置属性,用来指向创建它的函数对象的原型。原型对象也有一个[[proto]]属性。因此,在不断的指向中,形成了一个原型链。prototype原型对象在定义一个函数对象时,会包含一个预定义的属性prototype,称为原型对象。只有函数才有原型属性,也就是说__proto__的值是它对应的原型对象,函数的prototypeconstructor实例的constructor属性指向其构造函数的原型对象prototype上预定义的constructor属性,即用于引用其功能对象。这是一个循环引用。常有以下几种写法。添加constructor是因为重写了prototype对象,constructor属性消失了,需要手动添加。functionF(){};F.prototype={constructor:F,doSomething:function(){}}当JavaScript创建一个对象时,它会有一个[[proto]]内置属性,用来指向创建它的函数对象的原型。原型对象也有一个[[proto]]属性。因此,在不断的指向中,形成了一个原型链。原型链内存结构原型链终极探索图注意几个指向问题,下面详细分析Foo.prototype和Function.prototype指向Object.prototypeFoo()的__proto__指向Function.prototype其他函数对象构造函数指向Function,函数的构造函数指向实例对象原型链分析其自身的普通构造函数Myfun()这里相当于Foo()函数functionmyfun(x,y){this.x=xthis.y=ythis.sum=function(){returnx+y}}myfun.prototype.sum=function(){returnthis.x+this.y}myobj=newmyfun(1,2)console.log(myobj)非函数的原型链typefunctionobject常用的构造函数Array(),RegExp(),Date(),Boolean(),Number(),String()其实都是从Function构造出来的,从它们构造函数属性的指针可以证明,这里让我分析一下Array()的原型链。可以看到Array._proto_是一个函数,也就是说Array._proto_指向的Function.prototype是一个函数,其他常见对象的原型是ObjectArray.__proto__->Function.prototypeFunction.prototype是一个函数类型objectFunction.prototype.__proto__指向最顶层的Object.prototypeconsole.log(Array)Function函数对象的原型链在ES6标准中,Function对象有两个属性:长度值为1,这个属性的特点是{[[Writable]]:false,[[Enumerable]]:false,[[Configurable]]:true},即不能被覆盖,不能用于...在遍历中,但是可以通过Object.defineProperty作为原型对象修改上述属性的原型,(参见最新的ES标准描述Function.prototpye)它和一般函数的原型的区别在于它不能写,不能配置,或者Traversal意味着它总是指向一个固定的对象,是所有其他函数的原型对象,所有函数本身的__proto__都指向它。它是一个函数。一般函数的原型是普通对象,带有constructor属性,而Function的原型是函数对象(内置函数对象),是js中唯一默认原型是函数的对象。函数和对象都有__proto__属性,指向构造函数的prototype属性指向的对象,即它的原型对象。函数的__proto__属性(不是其原型对象prototype上的__proto__属性)指向Function.prototype,所以Function.prototype上的属性和方法会被函数对象继承。仿佛进入了“先有鸡还是先有蛋”的哲学范畴。Object本身就是一个构造函数,继承了Function.prototype;Function也是一个对象,继承了Object.prototype。Function.__proto__===Function.prototype//trueObject.__proto__===Function.prototype//trueObject.prototype.__proto__===null//trueFunction.prototype.__proto__===Object.prototype//trueObject.prototype===Object.__proto__//falseObjectinstanceofFunction//trueFunctioninstanceofObject//true不用担心鸡生蛋还是蛋生鸡。之所以Function.__proto__===Function.prototype是为了表明Function作为一个native构造器,它也是一个函数对象(自己构造的一个实例),这样Function构造器就可以获取到Object.prototype上定义的方法。console.log(Function)summary属性everythingisanobject注:都是我自己的看法,可能和标准的说法不一样,只是为了方便自己理解,我快晕了js中的everythingisanobject,最上面object就是一切Prototype(origin)注意这里的Object不是构造函数Object()是真正的原型对象Object(),Function(),Array(),String()这些方法就像我们自定义的方法一样(只是js语言帮助我们创建这些方法来创建特殊的类,这些方法本质上都是Objects。每个方法都有(可以说是创建了)自己的原型(prototypeobject),然后这些原型对象的_proto_都是指向最上面的——levelObject原型对象(所以可以解释为顶层对象创建每个方法的原型对象,也就是说方法类的原型对象和top的原型对象创建的实例是一样的级对象类)。Function方法比较特别,Object()、Array()、String()都是从Function方法构造出来的。Function构造器本身就是Function的一个实例(比如自己构造得到的函数对象),所以_proto_指向FunctionPrototype对象。再看看原型链的铁三角图。注意:当一个函数有两个状态作为构造函数时,可以去new一个实例对象。这个对象可以是普通对象,也可以是函数对象(Function可以是构造函数对象)作为构造函数(实例)对象,你自己的__proto__应该指向你自己的构造函数的原型(即指向原型对象)..com/a/1190000011880268https://segmentfault.com/a/1190000005363885https://juejin.im/post/5b3798f851882574c105c51chttps://github.com/creeperyang/blog/issues/9
