函数是对象,也就是说函数也是由若干属性组成的。JS默认给每个函数一个prototype属性,其值就是原型对象。
一、原型
每个函数都有一个prototype属性,其值是原型对象。原型对象默认只有一个constructor属性,指向这个函数本身。
原型对象也是对象,也是由若干属性组成的,不仅仅只有constructor属性。例如函数Object,其原型对象是Object.prototype。
当然,我们也可以在原型对象上自定义一些属性,然后进行访问。
function Fn(){
}
Fn.prototype.name = "张三";
Fn.prototype.age = 20;
var fn = new Fn();
console.log(fn.name);//张三
上述代码中,Fn是一个函数,fn对象是从Fn函数new出来的,这样fn对象就可以调用Fn.prototype中的属性。为什么fn对象可以访问到Fn原型对象中的属性?往下看
二、隐式原型
每个对象都有一个隐藏的属性,即__proto__属性。其值指向创建该对象的函数的原型对象,即
Fn.prototype也是对象,那么它也有__proto__属性。其值指向创建该对象的函数的原型对象。那么Fn.prototype原型对象是由什么函数创建的呢?它是个基本的对象,所以是由函数Object创建的。即
Object.prototype也是对象,那么它也有__proto__属性,但是它的值是指向null的。
用图总结下它们之间的关系:
看完上图关系,发现还有问题。函数也是对象,那函数应该也有__proto__属性。那其值指向谁呢?
其实函数都是有由函数Function创建出来的。例如:
var fn = new Function("x","y","return x+y;");
console.log(fn(2,3));
但是我们一般创建函数时不用上述方式,而是用如下方式 创建函数
function fn(x,y){
return x+y;
}
但是其实我们要知道:函数都是有由函数Function创建出来的。
另外还要注意两点:1、函数Funtion也是对象,其__proto__属性指向谁?其实它是指向自身原型对象,它是由它自身创建的。
2、Funtion.prototype原型对象是一个普通对象,其__proto__属性自然指向Object.prototype。
所以总的关系图如下:
三、原型链
在JS中,一切都是对象,而且任何对象都会有__proto__属性,所以会形成一条__proto__连起来的链条,这条链条称之为原型链,其终点指向null。
JS引擎查找对象属性时,先从自身属性查找,若没有,则沿着原型链去查找。