首先,函数有prototype属性,而对象(除Object)都有_proto_属性 _proto_可以理解为:构造器的prototype
_proto_指向谁呢
1.当以函数字面量的形式创建一个对象时
var a={};
_proto_指向Object的prototype
2.当以构造器的形式创建一个对象时
var A=function(){};
var a=new A();
_proto_指向创建它的那个函数的prototype
3.当以Object.create方式创建对象时
var a1={};
var a2=Object.create(a1);
_proto_指向Object.create()方法里面指定的原型对象。
_proto_的指向连接起来的链条,就是原型链。
例如 var A=funciton(){};
var a=new A();
a._proto_指向A.prototype;
A._proto_指向Object.prototype
Object.prototype.__proto__指向null
当js引擎查找对象的属性的时候,会先查找对象本身是否具有该属性,如果没有,逐层向上查找。
改变一个对象本身的属性,并不会引起原型链上属性的改变。
在原型链中,我们想要查找某一个对象的属性,如果该属性在当前对象所在的函数中查找,如果没有的话就会沿着原型链向上查找,找到的话就返回属性值,如果都没有的话就会返回undefined。
当我们使用new运算符创建一个对象时,实际上发生了以下过程:
var a=new A();
1.创建一个空对象var obj={};
2.将a的this指向空对象
3.将A的原型prototype指向obj的原型_proto_
4.执行A的构造函数
5.返回这个对象
看几道题
var F = function () {}
Object.prototype.a = function () {}
Function.prototype.b = function () {}
var f = new F()
f.a ?
F.a ?
f.b ?
F.b ?
答案是
[Function]
[Function]
undefined
[Function]
来看一下这道题中的原型链指向
f.__proto__ -> F.prototype.__proto__ -> Object.prototype.__proto__ -> null
F.__proto__ -> Function.prototype.__proto__ -> Object.prototype.__proto__ -> null (Function 是 F的构造函数)