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

首頁(yè) > 開(kāi)發(fā) > JS > 正文

分析javascript原型及原型鏈

2024-05-06 16:43:13
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

我們創(chuàng)建的每個(gè)函數(shù)都有一個(gè) prototype (原型)屬性,這個(gè)屬性是一個(gè)指針,指向一個(gè)原型對(duì)象,而這個(gè)原型對(duì)象中擁有的屬性和方法可以被所以實(shí)例共享。

function Person(){}Person.prototype.name = "Nicholas";Person.prototype.age = 29;Person.prototype.sayName = function(){alert(this.name);};var person1 = new Person();person1.sayName(); //"Nicholas"var person2 = new Person();person2.sayName(); //"Nicholas"alert(person1.sayName == person2.sayName); //true

一、理解原型對(duì)象

無(wú)論什么時(shí)候,只要?jiǎng)?chuàng)建了一個(gè)新函數(shù),就會(huì)根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個(gè) prototype屬性,這個(gè)屬性指向函數(shù)的原型對(duì)象。

在默認(rèn)情況下,所有原型對(duì)象都會(huì)自動(dòng)獲得一個(gè) constructor(構(gòu)造函數(shù))屬性,這個(gè)屬性包含一個(gè)指向 prototype 屬性所在函數(shù)的指針。

當(dāng)調(diào)用構(gòu)造函數(shù)創(chuàng)建一個(gè)新實(shí)例后,該實(shí)例的內(nèi)部將包含一個(gè)指針(內(nèi)部屬性),指向構(gòu)造函數(shù)的原型對(duì)象。ECMA-262 第 5 版中管這個(gè)指針叫 [[Prototype]] 。

雖然在腳本中沒(méi)有標(biāo)準(zhǔn)的方式訪(fǎng)問(wèn) [[Prototype]] ,但 Firefox、Safari 和 Chrome 在每個(gè)對(duì)象上都支持一個(gè)屬性__proto__ ;而在其他實(shí)現(xiàn)中,這個(gè)屬性對(duì)腳本則是完全不可見(jiàn)的。

不過(guò),要明確的真正重要的一點(diǎn)就是,這個(gè)連接存在于實(shí)例與構(gòu)造函數(shù)的原型對(duì)象之間,而不是存在于實(shí)例與構(gòu)造函數(shù)之間。

以前面使用 Person 構(gòu)造函數(shù)和 Person.prototype 創(chuàng)建實(shí)例的代碼為例,圖 6-1 展示了各個(gè)對(duì)象之間的關(guān)系。

javascript,原型,原型鏈

在此, Person.prototype 指向了原型對(duì)象,而 Person.prototype.constructor 又指回了 Person 。

person1 和 person2 都包含一個(gè)內(nèi)部屬性,該屬性?xún)H僅指向了 Person.prototype ;換句話(huà)說(shuō),它們與構(gòu)造函數(shù)沒(méi)有直接的關(guān)系。

可以調(diào)用 person1.sayName() 。這是通過(guò)查找對(duì)象屬性的過(guò)程來(lái)實(shí)現(xiàn)的。(會(huì)先在實(shí)例上搜索,如果搜索不到就會(huì)繼續(xù)搜索原型。)

 

用isPrototypeOf()方法判斷實(shí)例與原型對(duì)象之間的關(guān)系alert(Person.prototype.isPrototypeOf(person1)); //truealert(Person.prototype.isPrototypeOf(person2)); //true用Object.getPrototypeOf() 方法返回實(shí)例的原型對(duì)象alert(Object.getPrototypeOf(person1) == Person.prototype); //true使用 hasOwnProperty() 方法可以檢測(cè)一個(gè)屬性是存在于實(shí)例中,還是存在于原型中。alert(person1.hasOwnProperty("name")); //false  來(lái)著原型person1.name = "Greg";alert(person1.name); //"Greg"——來(lái)自實(shí)例alert(person1.hasOwnProperty("name")); //true

二、更簡(jiǎn)單的原型語(yǔ)法

前面例子中每添加一個(gè)屬性和方法就要敲一遍 Person.prototype 。為減少不必要的輸入,也為了從視覺(jué)上更好地封裝原型的功能,更常見(jiàn)的做法是用一個(gè)包含所有屬性和方法的對(duì)象字面量來(lái)重寫(xiě)整個(gè)原型對(duì)象。

function Person(){}Person.prototype = {  name : "Nicholas",  age : 29,  job: "Software Engineer",  sayName : function () {    alert(this.name);  }};

在上面的代碼中,我們將 Person.prototype 設(shè)置為等于一個(gè)以對(duì)象字面量形式創(chuàng)建的新對(duì)象。最終結(jié)果相同,但有一個(gè)例外: constructor 屬性不再指向 Person 了。

前面曾經(jīng)介紹過(guò),每創(chuàng)建一個(gè)函數(shù),就會(huì)同時(shí)創(chuàng)建它的 prototype 對(duì)象,這個(gè)對(duì)象也會(huì)自動(dòng)獲得 constructor 屬性。

var friend = new Person();alert(friend instanceof Object); //truealert(friend instanceof Person); //truealert(friend.constructor == Person); //falsealert(friend.constructor == Object); //true

在此,用 instanceof 操作符測(cè)試 Object 和 Person 仍然返回 true ,但 constructor 屬性則等于 Object 而不等于 Person 了。

如果 constructor 的值真的很重要,可以像下面這樣特意將它設(shè)置回適當(dāng)?shù)闹怠?/p>

function Person(){}Person.prototype = {  constructor : Person,  name : "Nicholas",  age : 29,  job: "Software Engineer",  sayName : function () {    alert(this.name);  }};  

三、原生對(duì)象的原型

所有原生引用類(lèi)型( Object 、 Array 、 String ,等等)都在其構(gòu)造函數(shù)的原型上定義了方法。

例如,在 Array.prototype 中可以找到 sort() 方法,而在 String.prototype 中可以找到substring() 方法。盡管可以這樣做,但不推薦修改原生對(duì)象的原型。

四、原型對(duì)象的問(wèn)題

原型模式的最大問(wèn)題是由其共享的本性所導(dǎo)致的。 修改其中的一個(gè),另一個(gè)也會(huì)受影響。

function Person(){}Person.prototype = {constructor: Person,name : "Nicholas",age : 29,job : "Software Engineer",friends : ["Shelby", "Court"],sayName : function () {alert(this.name);}};var person1 = new Person();var person2 = new Person();person1.friends.push("Van");alert(person1.friends); //"Shelby,Court,Van"alert(person2.friends); //"Shelby,Court,Van"alert(person1.friends === person2.friends); //true

五、原型鏈

其基本思想是利用原型讓一個(gè)引用類(lèi)型繼承另一個(gè)引用類(lèi)型的屬性和方法。然后層層遞進(jìn),就構(gòu)成了實(shí)例與原型的鏈條,這就是所謂原型鏈的基本概念。

function SuperType(){  this.property = true;}SuperType.prototype.getSuperValue = function(){  return this.property;};function SubType(){  this.subproperty = false;}//繼承了 SuperTypeSubType.prototype = new SuperType();SubType.prototype.getSubValue = function (){  return this.subproperty;};var instance = new SubType();alert(instance.getSuperValue()); //true

 一張圖說(shuō)明:

javascript,原型,原型鏈

 

property 則位于 SubType.prototype 中。這是因?yàn)?property 是一個(gè)實(shí)例屬性,而 getSuperValue() 則是一個(gè)原型方法。既然 SubType.prototype 現(xiàn)在是 SuperType的實(shí)例,那么 property 當(dāng)然就位于該實(shí)例中了。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JavaScript/Ajax教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 太原市| 方城县| 陆河县| 临江市| 图们市| 镇宁| 永川市| 章丘市| 海口市| 时尚| 平乡县| 靖江市| 沁水县| 微博| 那坡县| 宣城市| 连山| 壤塘县| 牡丹江市| 华阴市| 颍上县| 台中市| 枣强县| 海晏县| 文山县| 上虞市| 仙游县| 原平市| 西林县| 平昌县| 监利县| 繁昌县| 安新县| 武功县| 安远县| 聊城市| 湟中县| 万源市| 昆明市| 元阳县| 曲周县|