搜尋
首頁web前端js教程JS Pro-深入物件導向的程式設計之繼承的詳解_javascript技巧

原型鏈(prototype chaining):

利用原型來繼承屬性和方法。回顧一下建構子(constructor),原型物件(prototype)和實例(instance)的關係。每一個建構函數都有一個prototype屬性,該屬性指向一個prototype物件;prototype物件也有constructor屬性,指向該函數;而實例也有一個內部指標(__proto__)指向這個prototype物件。如果這個prototype物件是另一個物件的實例會是怎樣的呢?這樣該prototype物件就包含一個指向另一個類型的指針,相應地,另一個原型中也包含著一個指向另一個建構函數的指針。

JS的繼承很簡單,就是把子類別的prototype設為父類別的一個(實例化)物件

複製程式碼



複製程式碼


程式碼如下:


function SuperType(){
    this.property = true;
}

SuperType.prototype.get
}

SuperType.prototype.get. >    return this.property;
};

function SubType(){
    this.subproperty = false;
}
SubType.prototype.getSubValue = function (){

    return this.subproperty;

} Sub

alert(instance.getSuperValue());   //true

最終的結果:instance的__proto__指向SubType.prototype對象,而SubType.prototype對象的__proto__屬性又指向SuperType.prototype物件。 getSuperValue()是一個方法,所以仍然存在於原型中,而property是一個實例屬性,所以現在存在於SubType.prototype這個實例中。  instance.constructor現在指向的是SuperType,這是由於SubType.prototype指向SuperType.prototype,而SuperType.prototype的constructor屬性指向SuperType函數,所以instance.constructor指向SuperType。 預設情況下,所有參考類型都繼承Object。這是因為所有函數的原型對象,預設都是Object的一個實例,所以內部prototype(__proto__)指向Object.Prototype。 原型和實例的關係:可以使用2種方法來確定原型與實例之間的關係。
- instancef操作符:使用該操作符來測試實例與原型鏈中出現過的建構函數,都會傳回true




複製程式碼


程式碼如下:- isPrototypeOf()方法:只要是原型鏈中出現過的原型,都可以說是該原型鏈所衍生的實例的原型。




複製程式碼


程式碼如下:給子instance)); //true


給子instance)); //true


給子類別添加方法的注意點:我們有的時候會為子類別添加方法,或是重寫父類​​別的某些方法。這時候就要注意,這些方法必須在繼承後再定義。以下的範例裡,SubType在繼承SuperType後,我們為它增加了新的方法getSubValue(),而且重寫了getSuperValue()方法。對於後者,只有SubType的實例才會使用重寫的方法,SuperType的實例還是會使用原有的getSuperValue()方法。




複製程式碼


程式碼如下:


function SuperType(){


function SuperType(){

function SuperType(){
this.So. true;
}SuperType.prototype.getSuperValue = function(){  return this.property;};function SubType(){『 }//inherit from SuperTypeSubType.prototype = new SuperType();//new methodSubType.prototype.getSubValue = function (){this. subproperty;};//override existing methodSubType.prototype.getSuperValue = function (){  return false;};  return false;};}; alert(instance.getSuperValue()); //false
另一個需要注意的是,透過原型鏈實現繼承時,不能使用物件字面量來建立原型方法,因為這樣會重寫原型鏈。如下面的程式碼,在SubType繼承SuperType以後,使用物件字面量為原型添加方法,但這樣做,會重寫SubType原型,重寫後的SubType.prototype包含的是一個Object的實例,從而也切斷了與SuperType的關係。
複製程式碼 程式碼如下:

function SuperType(){


function SuperType(){

function SuperType(){
this.So. true;
}
SuperType.prototype.getSuperValue = function(){
  return this.property;
};
function SubType(){
〟『. 🎜>}
//inherit from SuperType
SubType.prototype = new SuperType();
//try to add new methods - this nullifies the previous line
SubType.prototype> getSubValue : function (){
    return this.subproperty;
  },
  someOtherMethod : function (){
  some returnevar instance = new SubType();
alert(instance.getSuperValue()); //error!

原型鏈的問題:
和原型一樣,當使用引用類型值的時候,原型鏈就會出問題了。回顧之前的內容,包含一個引用類型值的原型屬性會被所有實例共享,這就是為什麼我們要把引用類型值在建構函數中定義,而不是在原型中定義。透過原型鏈實現繼承時,原型實際上會變成另一個類型的實例,於是,原先的實例屬性也順利成章的變成現在的原型屬性了。 程式碼如下:


function SuperType(){


function SuperType(){


function SuperType(){
this =d. [“red”, “blue”, “green”];
}
function SubType(){
}
//inherit from SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();

instance1.colors.push(“black”);

alert(instance1.colors); //”red,blue,green,black”

var instance2 = new SubType();

alert(instance2.colors); //”red,blue,green,black”

在SuperType建構子中,我們定義了一個colors數組,每一個SuperType實例都會擁有它自己的這個colors陣列。但是當SubType使用原型鏈繼承SuperType以後,SubType.prototype變成SuperType的一個實例,因此它擁有自己的colors屬性,也就是說SubType.prototype.colors屬性。所以,當創建SubType實例的時候,所有實例都共享這項屬性了。如上面的程式碼所示。
第二個問題就是:在建立子類別的實例時,不能傳遞參數給超類別的建構子。實際上,應該說是沒有辦法在不影響所有物件實例的情況下,給超類別的建構函式傳遞參數。由於這些問題,我們不會單獨使用原型鏈。

----------------------------------------------- --------------------------------- 借用建構子(Contructor stealing):為了解決上述問題,開發人員發明了一種叫做借用建構函式的技術。這種技術的想法就是:在子類型建構函式的內部呼叫超類型建構函式。 (函數,只不過是在特定環境中執行程式碼的物件?)我們可以透過使用apply()或call()方法在新建立的物件上執行建構函數。


複製程式碼


程式碼如下:


function SuperType(){


function SuperType(){

function SuperType(){
this =d. [“red”, “blue”, “green”];}

function SubType(){
  //inherit from SuperType

  SuperType.call(this);}  SuperType.call(this);}}}var instance1 = new SubType();instance1.colors.push(“black”);alert(instance1.colors); //”red,blue,green,black”var instance2 = new SubType();
alert(instance2.colors); //”red,blue,green”我們在SubType裡使用call()方法呼叫SuperType的建構函數,實際上就是在新的SubType物件上執行SuperType()函數中定義的所有物件初始化程式碼。結果就是每個SubType實例都具有自己的colors屬性的副本。 傳遞參數:使用借用建構函式方法的一個很大的好處在於就是,我們可以從子類別的建構函式傳遞參數到父類別的建構函式中。 複製程式碼 程式碼如下:

function SuperType(name){
  this.name = name;
}
function SubType(){
  //〕 call(this, “Nicholas”);
  //instance property
  this.age = 29;
}
var instance = new SubType();
alert(instance.name); //”Nicholas”;
alert(instance.age); //29

新的SuperType建構子新增了一個參數name,我們在call SuperType的同時,往SuperType傳遞參數"Nicholas"。為了不讓超類型的建構子重寫子類型的屬性,可以在呼叫超類型建構函式後再定義子類別的屬性。

借用建構子的問題:方法都在建構子中定義,無法重複使用。而且在超類型的原型中定義的方法,對子類型而言是不可見的。結果所有型別都只能使用建構函數模式。

----------------------------------------------- ---------------------------------

組合繼承:
結合原型鍊及借用建構子各自的優點的一種繼承模式。使用原型鏈繼承原型屬性及方法,使用借用建構函式來繼承實例屬性。如下面例子,我們使用call()方法呼叫SuperType的建構子(每個SubType實例都擁有自己的name和colors屬性,以及SubType的age屬性);然後再把SuperType實例賦值給SubType的原型,使其繼承SuperType的sayName()方法(每個實例都共用這個方法)。

複製程式碼 程式碼如下:
f = name;
    this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function(){    alert(this.name);

};

function SubType(name, age){

    //inherit properties

    SuperType.call(this, name);
    this.age = age
;
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function(){
    alert(this.age);
};
};
};
var instance1 = new SubType("Nicholas", 29);

instance1.colors.push("black");

alert(instance1.colors); //"red,blue,green,black "
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2 .colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27


原型式繼承(Prototypal Inheritance):

複製程式碼複製程式碼

複製程式碼

function object(o){
  function F(){}
  F.prototype = o;
  return new F();}

  return new F();

}
--------- -------------------------------------------------- ---------------------


寄生式繼承(Parasitic Inheritance):

缺點同建構子
陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何使用JS和百度地图实现地图平移功能如何使用JS和百度地图实现地图平移功能Nov 21, 2023 am 10:00 AM

如何使用JS和百度地图实现地图平移功能百度地图是一款广泛使用的地图服务平台,在Web开发中经常用于展示地理信息、定位等功能。本文将介绍如何使用JS和百度地图API实现地图平移功能,并提供具体的代码示例。一、准备工作使用百度地图API前,首先需要在百度地图开放平台(http://lbsyun.baidu.com/)上申请一个开发者账号,并创建一个应用。创建完成

js字符串转数组js字符串转数组Aug 03, 2023 pm 01:34 PM

js字符串转数组的方法:1、使用“split()”方法,可以根据指定的分隔符将字符串分割成数组元素;2、使用“Array.from()”方法,可以将可迭代对象或类数组对象转换成真正的数组;3、使用for循环遍历,将每个字符依次添加到数组中;4、使用“Array.split()”方法,通过调用“Array.prototype.forEach()”将一个字符串拆分成数组的快捷方式。

如何使用JS和百度地图实现地图热力图功能如何使用JS和百度地图实现地图热力图功能Nov 21, 2023 am 09:33 AM

如何使用JS和百度地图实现地图热力图功能简介:随着互联网和移动设备的迅速发展,地图成为了一种普遍的应用场景。而热力图作为一种可视化的展示方式,能够帮助我们更直观地了解数据的分布情况。本文将介绍如何使用JS和百度地图API来实现地图热力图的功能,并提供具体的代码示例。准备工作:在开始之前,你需要准备以下事项:一个百度开发者账号,并创建一个应用,获取到相应的AP

如何使用JS和百度地图实现地图多边形绘制功能如何使用JS和百度地图实现地图多边形绘制功能Nov 21, 2023 am 10:53 AM

如何使用JS和百度地图实现地图多边形绘制功能在现代网页开发中,地图应用已经成为常见的功能之一。而地图上绘制多边形,可以帮助我们将特定区域进行标记,方便用户进行查看和分析。本文将介绍如何使用JS和百度地图API实现地图多边形绘制功能,并提供具体的代码示例。首先,我们需要引入百度地图API。可以利用以下代码在HTML文件中导入百度地图API的JavaScript

js中new操作符做了哪些事情js中new操作符做了哪些事情Nov 13, 2023 pm 04:05 PM

js中new操作符做了:1、创建一个空对象,这个新对象将成为函数的实例;2、将新对象的原型链接到构造函数的原型对象,这样新对象就可以访问构造函数原型对象中定义的属性和方法;3、将构造函数的作用域赋给新对象,这样新对象就可以通过this关键字来引用构造函数中的属性和方法;4、执行构造函数中的代码,构造函数中的代码将用于初始化新对象的属性和方法;5、如果构造函数中没有返回等等。

用JavaScript模拟实现打字小游戏!用JavaScript模拟实现打字小游戏!Aug 07, 2022 am 10:34 AM

这篇文章主要为大家详细介绍了js实现打字小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。

php可以读js内部的数组吗php可以读js内部的数组吗Jul 12, 2023 pm 03:41 PM

php在特定情况下可以读js内部的数组。其方法是:1、在JavaScript中,创建一个包含需要传递给PHP的数组的变量;2、使用Ajax技术将该数组发送给PHP脚本。可以使用原生的JavaScript代码或者使用基于Ajax的JavaScript库如jQuery等;3、在PHP脚本中,接收传递过来的数组数据,并进行相应的处理即可。

js是什么编程语言?js是什么编程语言?May 05, 2019 am 10:22 AM

js全称JavaScript,是一种具有函数优先的轻量级,直译式、解释型或即时编译型的高级编程语言,是一种属于网络的高级脚本语言;JavaScript基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式,如函数式编程。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中