構(gòu)造函數(shù)和原型對(duì)象
成都網(wǎng)絡(luò)公司-成都網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)十年經(jīng)驗(yàn)成就非凡,專業(yè)從事成都網(wǎng)站制作、做網(wǎng)站,成都網(wǎng)頁(yè)設(shè)計(jì),成都網(wǎng)頁(yè)制作,軟文營(yíng)銷,廣告投放等。十年來(lái)已成功提供全面的成都網(wǎng)站建設(shè)方案,打造行業(yè)特色的成都網(wǎng)站建設(shè)案例,建站熱線:028-86922220,我們期待您的來(lái)電!
構(gòu)造函數(shù)也是函數(shù),用new創(chuàng)建對(duì)象時(shí)調(diào)用的函數(shù),與普通函數(shù)的一個(gè)區(qū)別是,其首字母應(yīng)該大寫。但如果將構(gòu)造函數(shù)當(dāng)作普通函數(shù)調(diào)用(缺少new關(guān)鍵字),則應(yīng)該注意this指向的問(wèn)題。
var name = "Pomy"; function Per(){ console.log("Hello "+this.name); } var per1 = new Per(); //"Hello undefined" var per2 = Per(); //"Hello Pomy"
使用new時(shí),會(huì)自動(dòng)創(chuàng)建this對(duì)象,其類型為構(gòu)造函數(shù)類型,指向?qū)ο髮?shí)例;缺少new關(guān)鍵字,this指向全局對(duì)象。
可以用instanceof來(lái)檢測(cè)對(duì)象類型,同時(shí)每個(gè)對(duì)象在創(chuàng)建時(shí)都自動(dòng)擁有一個(gè)constructor屬性,指向其構(gòu)造函數(shù)(字面量形式或Object構(gòu)造函數(shù)創(chuàng)建的對(duì)象,指向Object,自定義構(gòu)造函數(shù)創(chuàng)建的對(duì)象則指向它的構(gòu)造函數(shù))。
console.log(per1 instanceof Per); //true console.log(per1.constructor === Per); //true
每個(gè)對(duì)象實(shí)例都有一個(gè)內(nèi)部屬性:[[Prototype]],其指向該對(duì)象的原型對(duì)象。構(gòu)造函數(shù)本身也具有prototype 屬性指向原型對(duì)象。所有創(chuàng)建的對(duì)象都共享該原型對(duì)象的屬性和方法。
function Person(){} Person.prototype.name="dwqs"; Person.prototype.age=20; Person.prototype.sayName=function() { alert(this.name); }; var per1 = new Person(); per1.sayName(); //dwqs var per2 = new Person(); per2.sayName(); //dwqs alert(per1.sayName == per2.sayName); //true
所以,實(shí)例中的指針僅指向原型,而不指向構(gòu)造函數(shù)。 ES5提供了hasOwnProperty()和isPropertyOf()方法來(lái)反應(yīng)原型對(duì)象和實(shí)例之間的關(guān)系
alert(Person.prototype.isPrototypeOf(per2)); //true per1.blog = "www.ido321.com"; alert(per1.hasOwnProperty("blog")); //true alert(Person.prototype.hasOwnProperty("blog")); //false alert(per1.hasOwnProperty("name")); //false alert(Person.prototype.hasOwnProperty("name")); //true
因?yàn)樵蛯?duì)象的constructor屬性是指向構(gòu)造函數(shù)本身,所以在重寫原型時(shí),需要注意constructor屬性的指向問(wèn)題。
function Hello(name){ this.name = name; } //重寫原型 Hello.prototype = { sayHi:function(){ console.log(this.name); } }; var hi = new Hello("Pomy"); console.log(hi instanceof Hello); //true console.log(hi.constructor === Hello); //false console.log(hi.constructor === Object); //true
使用對(duì)象字面量形式改寫原型對(duì)象改變了構(gòu)造函數(shù)的屬性,因此constructor指向Object,而不是Hello。如果constructor指向很重要,則需要在改寫原型對(duì)象時(shí)手動(dòng)重置其constructor屬性
Hello.prototype = { constructor:Hello, sayHi:function(){ console.log(this.name); } }; console.log(hi.constructor === Hello); //true console.log(hi.constructor === Object); //false
利用原型對(duì)象的特性,我們可以很方便的在JavaScript的內(nèi)建原型對(duì)象上添加自定義方法:
Array.prototype.sum=function(){ return this.reduce(function(prev,cur){ return prev+cur; }); }; var num = [1,2,3,4,5,6]; var res = num.sum(); console.log(res); //21 String.prototype.capit = function(){ return this.charAt(0).toUpperCase()+this.substring(1); }; var msg = "hello world"; console.log(msg.capit()); //"Hello World"
繼承
利用[[Prototype]]特性,可以實(shí)現(xiàn)原型繼承;對(duì)于字面量形式的對(duì)象,會(huì)隱式指定Object.prototype為其[[Prototype]],也可以通過(guò)Object.create()顯示指定,其接受兩個(gè)參數(shù):第一個(gè)是[[Prototype]]指向的對(duì)象(原型對(duì)象),第二個(gè)是可選的屬性描述符對(duì)象。
var book = { title:"這是書名"; }; //和下面的方式一樣 var book = Object.create(Object.prototype,{ title:{ configurable:true, enumerable:true, value:"這是書名", wratable:true } });
字面量對(duì)象會(huì)默認(rèn)繼承自O(shè)bject,更有趣的用法是,在自定義對(duì)象之間實(shí)現(xiàn)繼承。
var book1 = { title:"JS高級(jí)程序設(shè)計(jì)", getTitle:function(){ console.log(this.title); } }; var book2 = Object.create(book1,{ title:{ configurable:true, enumerable:true, value:"JS權(quán)威指南", wratable:true } }); book1.getTitle(); //"JS高級(jí)程序設(shè)計(jì)" book2.getTitle(); //"JS權(quán)威指南" console.log(book1.hasOwnProperty("getTitle")); //true console.log(book1.isPrototypeOf("book2")); //false console.log(book2.hasOwnProperty("getTitle")); //false
當(dāng)訪問(wèn)book2的getTitle屬性時(shí),JavaScript引擎會(huì)執(zhí)行一個(gè)搜索過(guò)程:現(xiàn)在book2的自有屬性中尋找,找到則使用,若沒(méi)有找到,則搜索[[Prototype]],若沒(méi)有找到,則繼續(xù)搜索原型對(duì)象的[[Prototype]],直到繼承鏈末端。末端通常是Object.prototype,其[[Prototype]]被設(shè)置為null。
實(shí)現(xiàn)繼承的另外一種方式是利用構(gòu)造函數(shù)。每個(gè)函數(shù)都具有可寫的prototype屬性,默認(rèn)被自懂設(shè)置為繼承自O(shè)bject.prototype,可以通過(guò)改寫它來(lái)改變?cè)玩湣?/p>
function Rect(length,width){ this.length = length; this.width = width; } Rect.prototype.getArea = function(){ return this.width * this.length; }; Rect.prototype.toString = function(){ return "[Rect"+this.length+"*"+this.width+"]"; }; function Square(size){ this.length = size; this.width = size; } //修改prototype屬性 Square.prototype = new Rect(); Square.prototype.constructor = Square; Square.prototype.toString = function(){ return "[Square"+this.length+"*"+this.width+"]"; }; var rect = new Rect(5,10); var square = new Square(6); console.log(rect.getArea()); //50 console.log(square.getArea()); //36
如果要訪問(wèn)父類的toString(),可以這樣做:
Square.prototype.toString = function(){ var text = Rect.prototype.toString.call(this); return text.replace("Rect","Square"); }
網(wǎng)站題目:JavaScript面向?qū)ο缶?下部)
鏈接分享:http://jinyejixie.com/article14/jjhhde.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、靜態(tài)網(wǎng)站、ChatGPT、移動(dòng)網(wǎng)站建設(shè)、營(yíng)銷型網(wǎng)站建設(shè)、虛擬主機(jī)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)