javascript繼承有「物件冒充」和「原型方式」兩種形式。物件冒充的本質上就是改變this指向;而原型方式的繼承,是指利用了prototype或說以某種方式覆寫了prototype,從而達到屬性方法複製的目的。
本教學操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。
Javascript本身是從Perl語言的語法演變而來的,本質上是腳本語言,隨著版本的更新逐漸加入的對物件導向的模擬。
我認為Js的物件導向模擬整體上做得還是不錯的,因為我們不能盲從任何一種理念,不能純粹的為了OOP而OOP,我們需要抓住的是物件導向的好處到底是什麼?為了這些優點去OOP, 才是最明智的選擇,所以說Js做得還不錯。
Js的繼承在許多書裡面細緻的分了很多種型別和實作方式,大體上就是兩種:物件冒充、原型方式。 這兩種方式各有優點和缺陷,這裡我先列舉出來,再從底層分析區別:
(一)物件冒充
function A(name){ this.name = name; this.sayHello = function(){alert(this.name+” say Hello!”);}; } function B(name,id){ this.temp = A; this.temp(name); //相当于new A(); delete this.temp; //防止在以后通过temp引用覆盖超类A的属性和方法 this.id = id; this.checkId = function(ID){alert(this.id==ID)}; }
當建構物件B的時候,呼叫temp相當於啟動A的建構函數,注意這裡的上下文環境中的this物件是B的實例,所以在執行A建構函數腳本時,所有A的變數和方法都會賦值給this所指的對象,即B的實例,這樣子就達到B繼承了A的屬性方法的目的。
之後刪除臨時引用temp,是防止維護B中對A的類別物件(注意不是實例物件)的參考更改,因為更改temp會直接導致類別A(注意不是類別A的物件)結構的變化。
我們看到了,在Js版本更新的過程中,為了更方便的執行這種上下文this的切換以達到繼承或者更加廣義的目的,增加了call和apply函數。它們的 原理是一樣的,只是參數不同的版本罷了(一個可變任意參數,一個必須傳入數組作為參數集合)。這裡就以call為例子,解釋一下用call實作的物件冒充 繼承。
function Rect(width, height){ this.width = width; this.height = height; this.area = function(){return this.width*this.height;}; } function myRect(width, height, name){ Rect .call(this,width,height); this.name = name; this.show = function(){ alert(this.name+” with area:”+this.area()); } }
關於Call方法,官方解釋:呼叫一個物件的一個方法,以另一個物件取代目前物件。
call (thisOb,arg1, arg2…)
這也是一種物件冒充的繼承,其實在call方法呼叫的時候發生的事情也是上下文環境變數this的替換,在myRect函數體中this肯定是指向類別myRect物件的實例了,然而用這個this作為上下文環境變數呼叫名字叫Rect方法,也就是類別Rect的建構子。
於是此時呼叫Rect時候對this 的賦值屬性和方法都其實是對一個myRect的物件進行。所以說儘管call和apply並不是僅僅為了繼承而新增的方法,但用它們可以模擬繼承。
物件冒充繼承就是這麼一回事,它可以實現多重繼承,只要重複做這套賦值的流程就可以了。不過目前真正大規模使用得不多,為什麼呢?
因為它有一個明顯的效能缺陷,這就要說道OO的概念了,我們說物件是成員成員方法的集合,建構物件實例的時候,這些實例只需要擁有各自的成員變數就可以了,成員方法只是一段對變數操作的可執行文字區域而已,這段區域不用為每個實例而複製一份,所有的實例都可以共享。
現在回到Js利用物件冒充模擬的繼承裡,所有的成員方法都是針對this而創建的,也就是所所有的實例都會擁有一份成員方法的副本,這是對記憶體資源的一種極度浪費。
其它的缺陷比如說物件冒充無法繼承 prototype域的變數和方法就不用提了,筆者認為前一個致命缺陷就已經足夠。不過,我們還是需要去理解它,特別是父類別的屬性和方法是如何繼承下來的原 理,對於理解Js繼承很重要。
【推薦學習:javascript高階教學】
(二)原型方式
第二種繼承方式是原型方式,所謂原型方式的繼承,是指利用了prototype或者說以某種方式覆蓋了prototype,從而達到屬性方法複製的目的。其實現方式有很多中,可能不同框架多少會有一點區別,但是我們把握住原理,就不會有任何不理解的地方了。看一個例子(某一種實作):
function Person(){ this.name = “Mike”; this.sayGoodbye = function(){alert(“GoodBye!”);}; } Person.prototype.sayHello = function(){alert(”Hello!”);}; function Student(){} Student.prototype = new Person();
關鍵是對最後一句Student原型屬性賦值為Person類別建構的對象,這裡筆者解釋一下父類別的屬性和方法是如何copy到子類別上的。
Js物件在讀取某個物件屬性的時候,總是先查看自身域的屬性列表,如果有就返回否則去讀取prototype域,如果找到就返回,由於prototype可以指向別的對象,所以Js解釋器會遞歸的去查找prototype域指向對象的prototype域,直到prototype為本身就停止,此時還沒找到就成undefined了。
这样看来,最后一句发生的效果就是将父类所有属性和方法连接到子类的prototype域上,这样子类就继承了父类所有的属性和方法,包括name、 sayGoodbye和sayHello。这里与其把最后一句看成一种赋值,不如理解成一种指向关系更好一点。
这种原型继承的缺陷也相当明显,就是继承时 父类的构造函数时不能带参数,因为对子类prototype域的修改是在声明子类对象之后才能进行,用子类构造函数的参数去初始化父类属性是无法实现的, 如下所示:
function Person(name){ this.name = name; } function Student(name,id){ this.id = id; } Student.prototype = new Person(this.name);
两种继承方式已经讲完了,如果我们理解了两种方式下子类如何把父类的属性和方法“抓取”下来,就可以自由组合各自的利弊,来实现真正合理的Js继承。下面是个人总结的一种综合方式:
function Person(name){ this.name = name; } Person.prototype.sayHello = function(){alert(this.name+“say Hello!”);}; function Student(name,id){ Person.call(this,name); this.id = id; } Student.prototype = new Person(); Student.prototype.show = function(){ alert(“Name is:”+ this.name+” and Id is:”+this.id);
总结就是利用对象冒充机制的call方法把父类的属性给抓取下来,而成员方法尽量写进被所有对象实例共享的prototype域中,以防止方法副本重复创 建。然后子类继承父类prototype域来抓取下来所有的方法。
如想彻底理清这些调用链的关系,推荐大家多关注Js中prototype的 constructor和对象的constructor属性,这里就不多说了。
更多编程相关知识,请访问:编程视频!!
以上是javascript繼承有哪兩種形式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

記事本++7.3.1
好用且免費的程式碼編輯器

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

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

Dreamweaver CS6
視覺化網頁開發工具