原型链:
每个函数都可以成为构造函数,每个函数都有原型对象,每个原型对象也可以是一个实例化对象,比如,你创建了一个函数fun,它是构造函数function的实例化对象,而function的原型对象,又是Object的实例对象。所以fun有个_proto_属性可以访问到function的原型对象,function原型对象也是个实例对象,也有个_proto_属性,可以访问到Object的原型对象,所以通过_proto_属性,就形成了一条原型链。每个实例化对象都可以访问到链子上方的方法和属性,所以fun是可以访问Object原型对象下的方法和属性的。实际上所有对象都可以访问到Object的原型对象。
原型链的访问规则:先在自身的下面寻找,再去一级一级的往原型链上找。
如下:
function Aaa(){} Aaa.prototype.num = 3; var a1 = new Aaa(); a1.num =10; alert(a1.num); //10
原型对象:
原型对象下可能有三种属性:
1 原型对象所带方法和属性 2 constructor 3_proto_属性
constructor:构造函数属性,每个函数的原型对象都有的默认属性,指向函数。
每个实例化对象本身是没有constructor属性的,他们下面默认只有一个_proto_属性,用来连接原型对象,而和构造函数本身是没有直接的联系的。所以它的constructor是访问的原型对象上的。所以当原型对象的constructor变化了,实例化对象的constructor也会改变。但是如果这个对象本身既是原型对象,又是实例化对象,那就拥有了constructor属性,无需从原型对象上面访问。**
看下面的例子,来验证我们所说的:
function CreatePerson(name){ this.name = name; } CreatePerson.prototype.showName = function(){ console.log(this.name); }; var p1 =new CreatePerson('haha'); p1.showName(); console.log(p1.constructor); // CreatePerson 来自CreatePerson.prototype console.log(CreatePerson.prototype); // {showName:{},constructor:CreatePerson,__proto__:Object.prototype} //可见,原型对象保存了 1 自身添加的方法, 2 构造函数constructor 3 _proto_(和上一层构造函数原型对象的连接) console.log(CreatePerson.prototype.__proto__===Object.prototype); // true 这个原型对象本身又是object的实例化对象,所有_proto_指向Object的原型对象 console.log(CreatePerson.prototype.__proto__===Object); // false 可见是和构造函数下原型对象的连接,不是构造函数 console.log(CreatePerson.prototype.constructor); //CreatePerson CreatePerson.prototype是Object实例化对象,也是原型对象,所以自身拥有constructor属性 console.log(Object.prototype.__proto__); // null 原型链的终点是null console.log(CreatePerson.__proto__); //function.prototype // CreatePerson本身既是构造函数又是function的实例化对象,拥有_proto_属性,指向function的原型对象 console.log(CreatePerson.constructor); // function 继承自function.prototype console.log(CreatePerson.prototype instanceof CreatePerson ) //验证是否在一条原型链上 false
字面量法定义原型:
为了创建对象的代码更方便,你一定见过这样的代码,就是字面量法:
function Aaa(){} Aaa.prototype = { showName:function(){}, showSex:function(){} }; var a1 = new Aaa(); console.log(Aaa.prototype); //{showName:function(){},_proto_} //你会发现constructor不见了,因为这种方式相当于重新赋值了Aaa.prototype console.log(Aaa.prototype.constructor); //Object 因为自身没有了constructor属性,就去上级原型对象找,找到了Object console.log(a1.constructor ); //Object 也变了,验证了它是访问的原型对象上的
因此我们在写的时候需要修正一下原型的指向:
function Aaa(){} Aaa.prototype = { constructor:Aaa, num1:function(){alert(10);} } var a1 = new Aaa(); a1.constructor // Aaa
Atas ialah kandungan terperinci javascript原型链和原型对象属性实例详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!