好记性不如烂笔头,在写作的过程中自己消化吸收,所以写下这个JavaScript学习系列文章。文章中的文字都是自己一一敲字敲下来的,都是自己理解的内容,各位酌情观看。
上一讲说到原型,复杂的图其实说的是原型链。那什么是原型链呢:原型也是对象,他也有自己的原型,那么这样就够成了一个原型链。
在这个复杂的图中,我们先看f1 f2,这是两个实例,通过Foo函数创建的两个实例,自然他们隐式带有__proto__属性,并且指向了Foo.prototype原型,可以通过f1.__proto__访问查看。那么问题来了,上回说到prototype也是个对象,那他的原型是谁呢?
首先我们来看一段代码:
// 函数声明
function Foo() {
var val ="2021";
console.log(val);//2021
}
var f1=new Foo();
var f2=new Object();
f2.val="2021";
console.log(f2.val);//2021
在这段代码中我们声明了一个函数Foo,他有个属性值val,通过new方法创建了一个Foo的实例对象f1;通过Object对象创建了实例f2,给他增加了个val属性;现在两个实例是“等价”的。这个例子就是想说JavaScript的对象实际上是通过创建一个空的Object对象。函数Foo的prototype就是通过Object对象构建的实例。这里再重复一下:实例的__proto__指向构造这个实例的prototype原型;因此,这里的Foo.prototype.__proto__指向了Object对象的prototype;
同样的流程,哦o1,o2实例对象也是由Object函数对象构建,形成了他们的一个原型链流程。他们原型链最终都指向了Object.prototype。而Object.prototype也是一个对象(实例),它的原型(__proto__)指向null(最终)。
没有结束的是,函数Foo、函数Object它也是对象,他对f1(或o1)来说是构造函数(函数对象),他有prototype原型。他自身也是被创建的对象(实例对象),他也有自己的原型__proto__,那他的原型指向哪里呢?换句话说,函数是被谁创建出来的呢?Function(大写的F)
var fn = function (x) {
return x*x;
}
console.log(fn(3));
var fm = Function ("x","return x*x");
console.log(fm(3));
函数就是被Function函数创建的。所以Foo、Object他们的__proto__原型属性指向Function的prototype。Function.prototype.__proto__指向Object的prototype。至此只剩一个对象没有找到原型,Function.__proto__。这里大佬是这么理解的:Function也是一个函数,函数是一种对象,也有__proto__属性。既然是函数,那么它一定是被Function创建。所以——Function是被自身创建的。所以它的__proto__指向了自身的Prototype。
这就是所有的原型链内容了。总结一下“公式”:
1.所有的对象都有自己的原型属性__proto__,这个原型属性指向构造这个对象的函数的prototype原型。
2.所有的函数对象都有自己的prototype原型,这个prototype原型是普通Object函数构造的,由1可知函数的prototype的__proto__指向Object.prototype。Object.prototype的__proto__指向null
3.函数的prototype自带constructor属性,指向构造函数本身。
原型、原型链完。