国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript面向對象精要(下部)

2019-11-19 15:28:36
字體:
來源:轉載
供稿:網友

構造函數和原型對象

構造函數也是函數,用new創建對象時調用的函數,與普通函數的一個區別是,其首字母應該大寫。但如果將構造函數當作普通函數調用(缺少new關鍵字),則應該注意this指向的問題。

var name = "Pomy";function Per(){  console.log("Hello "+this.name);}var per1 = new Per(); //"Hello undefined"var per2 = Per();  //"Hello Pomy"

使用new時,會自動創建this對象,其類型為構造函數類型,指向對象實例;缺少new關鍵字,this指向全局對象。

可以用instanceof來檢測對象類型,同時每個對象在創建時都自動擁有一個constructor屬性,指向其構造函數(字面量形式或Object構造函數創建的對象,指向Object,自定義構造函數創建的對象則指向它的構造函數)。

console.log(per1 instanceof Per); //trueconsole.log(per1.constructor === Per); //true

每個對象實例都有一個內部屬性:[[Prototype]],其指向該對象的原型對象。構造函數本身也具有prototype 屬性指向原型對象。所有創建的對象都共享該原型對象的屬性和方法。

function Person(){}Person.prototype.name="dwqs";Person.prototype.age=20;Person.prototype.sayName=function(){  alert(this.name);};var per1 = new Person();per1.sayName(); //dwqsvar per2 = new Person();per2.sayName(); //dwqsalert(per1.sayName == per2.sayName); //true

所以,實例中的指針僅指向原型,而不指向構造函數。 ES5提供了hasOwnProperty()和isPropertyOf()方法來反應原型對象和實例之間的關系

alert(Person.prototype.isPrototypeOf(per2)); //trueper1.blog = "www.ido321.com";alert(per1.hasOwnProperty("blog")); //truealert(Person.prototype.hasOwnProperty("blog")); //falsealert(per1.hasOwnProperty("name")); //falsealert(Person.prototype.hasOwnProperty("name")); //true

因為原型對象的constructor屬性是指向構造函數本身,所以在重寫原型時,需要注意constructor屬性的指向問題。

function Hello(name){  this.name = name;}//重寫原型Hello.prototype = {  sayHi:function(){    console.log(this.name);  }};var hi = new Hello("Pomy");console.log(hi instanceof Hello); //trueconsole.log(hi.constructor === Hello); //falseconsole.log(hi.constructor === Object); //true

使用對象字面量形式改寫原型對象改變了構造函數的屬性,因此constructor指向Object,而不是Hello。如果constructor指向很重要,則需要在改寫原型對象時手動重置其constructor屬性

Hello.prototype = {  constructor:Hello,  sayHi:function(){    console.log(this.name);  }};console.log(hi.constructor === Hello); //trueconsole.log(hi.constructor === Object); //false

利用原型對象的特性,我們可以很方便的在JavaScript的內建原型對象上添加自定義方法:

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); //21String.prototype.capit = function(){  return this.charAt(0).toUpperCase()+this.substring(1);};var msg = "hello world";console.log(msg.capit()); //"Hello World"

繼承

利用[[Prototype]]特性,可以實現原型繼承;對于字面量形式的對象,會隱式指定Object.prototype為其[[Prototype]],也可以通過Object.create()顯示指定,其接受兩個參數:第一個是[[Prototype]]指向的對象(原型對象),第二個是可選的屬性描述符對象。

var book = {  title:"這是書名";};//和下面的方式一樣var book = Object.create(Object.prototype,{  title:{    configurable:true,    enumerable:true,    value:"這是書名",    wratable:true  }});

字面量對象會默認繼承自Object,更有趣的用法是,在自定義對象之間實現繼承。

var book1 = {  title:"JS高級程序設計",  getTitle:function(){    console.log(this.title);  }};var book2 = Object.create(book1,{  title:{    configurable:true,    enumerable:true,    value:"JS權威指南",    wratable:true  }});book1.getTitle(); //"JS高級程序設計"book2.getTitle(); //"JS權威指南"console.log(book1.hasOwnProperty("getTitle")); //trueconsole.log(book1.isPrototypeOf("book2")); //falseconsole.log(book2.hasOwnProperty("getTitle")); //false

當訪問book2的getTitle屬性時,JavaScript引擎會執行一個搜索過程:現在book2的自有屬性中尋找,找到則使用,若沒有找到,則搜索[[Prototype]],若沒有找到,則繼續搜索原型對象的[[Prototype]],直到繼承鏈末端。末端通常是Object.prototype,其[[Prototype]]被設置為null。

實現繼承的另外一種方式是利用構造函數。每個函數都具有可寫的prototype屬性,默認被自懂設置為繼承自Object.prototype,可以通過改寫它來改變原型鏈。

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()); //50console.log(square.getArea()); //36

如果要訪問父類的toString(),可以這樣做:

Square.prototype.toString = function(){  var text = Rect.prototype.toString.call(this);  return text.replace("Rect","Square");}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 淮滨县| 巍山| 蒙城县| 常州市| 梁山县| 师宗县| 南皮县| 栖霞市| 杭锦后旗| 宁波市| 宜春市| 洱源县| 花莲县| 舟曲县| 全椒县| 商南县| 绥阳县| 太仓市| 荔浦县| 象山县| 越西县| 谢通门县| 林州市| 牡丹江市| 高密市| 呼玛县| 南通市| 洪江市| 吐鲁番市| 茂名市| 沽源县| 桐梓县| 洛川县| 承德县| 五台县| 铜梁县| 桐柏县| 沙坪坝区| 利津县| 通州市| 陆丰市|