原型鏈:
每個函數都可以成為建構函數,每個函數都有原型對象,每個原型對像也可以是一個實例化對象,例如,你創建了一個函數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
以上是javascript原型鍊和原型物件屬性實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!