透過本文帶領大家一起重新理解JavaScript的六種繼承方式,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
類別繼承(建構子)
JS中其實是沒有類別的概念的,所謂的類別也是模擬出來的。特別是當我們是用new 關鍵字的時候,就使得「類別」的概念就越像其他語言中的類別了。類別式繼承是在函數物件內呼叫父類別的建構函數,使得自身獲得父類別的方法和屬性。 call和apply方法為類別繼承提供了支援。透過改變this的作用環境,使得子類別本身俱有父類別的各種屬性。
var father = function() { this.age = 52; this.say = function() { alert('hello i am '+ this.name ' and i am '+this.age + 'years old'); } } var child = function() { this.name = 'bill'; father.call(this); } var man = new child(); man.say();
原型繼承
原型繼承在開發中常用到。它有別於類別繼承是因為繼承不在物件本身,而在物件的原型上(prototype)。每一個物件都有原型,在瀏覽器中它體現在一個隱藏的proto屬性上。在一些現代瀏覽器中你可以更改它們。例如在zepto中,就是透過將zepto的fn物件加到一個空的陣列的proto屬性上去,從而使得該數組成為一個zepto物件並且擁有所有的方法。話說回來,當一個物件需要呼叫某個方法時,它會回去最近的原型上尋找該方法,如果沒有找到,它會再次往下繼續查找。這樣逐級查找,一直找到了要找的方法。 這些查找的原型構成了該物件的原型鏈。原型最後指向的是null。我們說的原型繼承,就是將父物件的方法給子類別的原型。子類別的建構函式中不擁有這些方法和屬性。
var father = function() { } father.prototype.a = function() { } var child = function(){} //开始继承 child.prototype = new father(); var man = new child(); man.a();
可以看到第七行實作了原型繼承。很多人並不陌生這種方式。透過在瀏覽器中列印man我們就可以查看各個原型的繼承關係。
可以看到逐級的關係child->object(father實例化的物件)->father。 child是透過中間層繼承了father的原型上的東西的。但是為什麼中間還有一層object呢, 為什麼不把child.prototype = father.prototype。 答案是如果這樣做child和father就沒有差別了。大家應該還記得在prototype中有個constructor屬性,指向的是建構子。依照正常的情況我們要把constructor的值改回來指向child的建構子。但如果直接把father.prototype賦值給child.prototype,那麼constructor該指向誰呢?所以很顯然只能透過中間層才能使得child和father保持為獨立的物件。
類別式繼承與原型繼承的比較
#建構子(類別)式繼承
#首先,建構函式繼承的方法都會存在父物件之中,每一次實例,都會將funciton保存在記憶體中,這樣的做法毫無以為會帶來效能上的問題。
其次,類別繼承是不可變的。無法復用,在運行時,無法修改或添加新的方法,這種方式是一種固步自封的死方法。實務上很少單純使用。
原型繼承
優點:
原型鏈可改變:原型鏈上的父類別可替換可擴展
可以透過改變原型連結而對子類別進行修改的。另外就是類別繼承不支援多重繼承,而對於原型繼承來說,你只需要寫好extend對物件進行擴充即可。
但是原型鏈繼承也有2個問題。
第一,包含引用類型值的原型屬性會被所有實例共享(可以這樣理解:執行sub1.arr.push(2);先對sub1進行屬性查找,找遍了實例屬性(在本例中沒有實例屬性),沒找到,就開始順著原型鏈向上找,拿到了sub1的原型對象,一搜身,發現有arr屬性。 sub2.arr也變了)。
第二,在建立子類型的實例時,不能傳遞參數給超類型的建構函式。 (實際上,應該說沒有辦法在不影響所有物件實例的情況下,給超類型的建構函式傳遞參數)實踐中很少單純使用原型鏈。
function Super(){ this.val = 1; this.arr = [1]; } function Sub(){ // ... } Sub.prototype = new Super(); // 核心 var sub1 = new Sub(); var sub2 = new Sub(); sub1.val = 2; sub1.arr.push(2); alert(sub1.val); // 2 alert(sub2.val); // 1 alert(sub1.arr); // 1, 2 alert(sub2.arr); // 1, 2
總結:
類別式繼承在實例化時,父類別可傳參,無法重複使用(父類別不可變,每一次實例都會將父類別內容保存在記憶體中)
原型继承在实例化时,父类不可传参,可以复用(原型链可改变(父类可替换可扩展),父类不会保存在内存中,而是顺着原型链查找,但是结果是原型属性会被所有实例共享(尤其影响引用类型值))
组合继承(最常用)
组合继承将原型链和借用构造函数的技术结合到一起,发挥两者之长的一种继承模式。
思路是使用原型链实现对原型属性和方法的继承,通过借用构造函数实现对实例属性的继承。
function SuperType(name){ this.name = name; this.numbers = [1,2,3]; } SuperType.prototype.sayName = function(){ console.log(this.name); } function SubType(name,age){ SuperType.call(this,name); this.age = age; } SubType.prototype = new SuperType(); SubType.prototype.sayAge = function(){ console.log(this.age); } var instance1 = new SubType('aaa',21); instance1.numbers.push(666); console.log(instance1.numbers); instance1.sayName(); instance1.sayAge(); var instance2 = new SubType('bbb',22); console.log(instance2.numbers); instance2.sayName(); instance2.sayAge();
把实例函数都放在原型对象上,通过Sub.prototype = new Super();继承父类函数,以实现函数复用。
保留借用构造函数方式的优点,通过Super.call(this);继承父类的基本属性和引用属性,以实现传参;
优缺点
优点:
可传参
函数可复用
不存在引用属性共享问题(图纸)
缺点:
(一点小瑕疵)子类原型上有一份多余的父类实例属性,因为父类构造函数被调用了两次,生成了两份,而子类实例上的那一份屏蔽了子类原型上的。。。又是内存浪费,比刚才情况好点,不过确实是瑕疵。
以上是深入理解JavaScript的六種繼承方式(圖文)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

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

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。