
随着前端項目越來越大,如何使開發的代碼更易拓展、更易維護、可讀性更強等成為首要問題,是以越來越多的企業采用面向對象的開發技術。
但 ECMAScript 6之前的JavaScript版本中,并沒有實作類、繼承等技術,是以需要手動模拟實作,這給我們帶來了更多的靈活性。
針對不同的需求,有不同的實作。我們在掌握這些技術實作的同時,要更多地了解其适用于哪些需求。
1、JavaScript是怎麼樣實作繼承的?請舉例說明。
JavaScript通過 prototype屬性實作繼承,繼承的屬性方法是共享的,例如Chid子類繼承 Parent父類, Child. prototype= new Parento()。
在子類構造函數内執行父類構造函數,并傳遞子類作用域和參數,進而實作對父類構造函數的繼承,例如 function Child(){ Parent. apply(this, arguments)}。
2、簡述如何通過new建構對象?
通過new操作符建構對象的步驟如下。
(1)建立一個新的對象,這個對象的類型是 object.
(2)将this變量指向該對象。
(3)将對象的原型指向該構造函數的原型。
(4)執行構造函數,通過this對象,為執行個體化對象添加自身屬性方法。
(5)将this引用的新建立的對象傳回。
代碼如下。
function demo(Base) {
var obj ={};
//this =obj
obj. __proto__= Base. prototype;
School.call(obj)
return obj
}
3、談談 JavaScript中繼承的實作方法。
子類的執行個體可以共享父類的方法;子類可以覆寫從父類擴充來的方法。
4、說說構造函數的特點。
構造函數的函數名首字母大寫,構造函數類似于一個模闆,可以使用new關鍵字執行構造函數,建立執行個體化對象。
5、小賢是一條可愛的小狗(Dog),它的叫聲很好聽(wow),每次看到主人的時候就會乖乖叫一聲(yelp)b根據這段描述,請用程式實作。
代碼如下。
function Dog(){}
Dog.prototype.wow=function(){
console.log('wow')
}
Dog.prototype.yelp=function(){
this.wow();
}
var xx=new Dog()
xx.yelp();//wow
6、小芒( Mad Dog)和小賢一樣,原來也是一條可愛的小狗,可是突然有一天瘋了,一看到人就會每隔0.5s叫一聲(wow),且不停叫喚(yelp)b根據描述,請用代碼來實作。
代碼如下
function MadDog(){}
MadDog.prototype= new Dog();
MadDog.prototype.yelp=function(){
var me= this:
setInterval(function(){
me. wow()
},500)
var madDog= new MadDog();
madDog.yelp()
7、列出 JavaScript常用繼承方式并說明其優缺點。
常用繼承方式及其優缺點如下。
(1)構造函數式繼承是指在子類的作用域上,執行父類的構造函數,并傳遞參數構造函數式繼承雖然解決了對父類構造函數的複用問題,但沒有更改原型。
(2)類(原型鍊)式繼承是指将父類的執行個體化對象添加給子類的原型。執行構造函數是沒有意義的,因為我們隻想繼承原型鍊上的屬性和方法,當執行父類的構造函數時,沒有添加參數,是以執行構造函數的結果是不正确的。父類構造函數中的資料,沒有直接添加在子類的執行個體化對象上,而是添加在原型上。子類型執行個體化時無法複用父類的構造函數。
(3)組合式繼承是比較常用的一種繼承方法,其背後的思路是,使用原型鍊實作對原型屬性和方法的繼承,而通過構造函數來實作對執行個體屬性的繼承。這樣,既在原型上定義方法實作了函數複用,又保證每個執行個體都有它自己的屬性。但其問題是導緻父類的構造函數執行了兩次:一次是在構造函數式繼承中執行的;另一次是在類式繼承中執行的。
使用上述繼承要注意以下幾點
(1)在構造函數式繼承中,屬性的指派一定在繼承的後面執行,否則會産生覆寫問題。
(2)在類式繼承中,原型上屬性或者方法的指派一定在繼承後面,否則會産生覆寫問題。
(3)在類式繼承中,在原型上添加屬性或者方法一定使用點文法的形式,不可以給對象指派。
(4)在類式繼承中,要為原型添加屬性方法對象,可以在繼承後面通過庫的 extend方法(或 ECMAScript6提供了 assign方法)實作。
8、用 JavaScript寫一個實作寄生式繼承的方法。
以下代碼實作了寄生式繼承方法 inherit。
var inherit =(function(){
//定義寄生類
function F(){};
return function(sub, sup) {
//寄生類的原型指向父類
E.prototype= sup.prototype;
//繼承父類的原型
sub.prototype=new F ();
//更正構造函數
sub.prototype.constructor =sub;
//傳回子類
return sub;
}
})()
//父類
function Star(names){
this.names = names
}
Star.prototype.getNames = function(){
return this.names
//子類
function Moviestar(names, age) {
//構造函數式繼承
Star.apply(this, arguments)
this.age = age;
//寄生式繼承
inherit(Moviestar, star);
MovieStar.prototype.getAge =function (){
return this.age;
}
console. log(new Moviestar( 'xiao bai', 20))
9、說出你熟知的 Javascript繼承方式。
有以下幾種繼承方式
(1)構造函數式繼承。
(2)類(原型鍊)式繼承。
(3)組合式繼承(混合使用構造函數式和類式)。
(4)寄生式繼承。
(5)繼承組合式繼承(混合使用構造函數式和寄生式)。
(6)原子繼承。
(7)多繼承。
(8)靜态繼承。
(9)特性繼承。
(10)構造函數拓展式繼承。
(11)工廠式繼承
10、面向對象的特性有哪些?
有以下特性。
(1)抽象,就是忽略一個主題中與目前目标無關的那些方面,以便更充分地關注與目前目标相關的方面。
(2)封裝,利用抽象資料類型将資料和基于資料的操作封裝在一起,使其構成一個不可分割的獨立實體。資料存放在抽象資料類型的内部,盡可能地隐藏内部的細節,隻保留一些對外接口,使之與外部發生聯系。
(3)繼承,使用已存在的類的定義作為基礎,建立新類的技術。新類的定義可以增加新的資料或新的功能,也可以用父類的功能,但不能選擇性地繼承父類。
(4)多态,程式中定義的引用變量所指向的具體類型和通過該引用變量觸發的方法調用在程式設計時并不确定,而在程式運作期間才能确定,即一個引用變量到底會指向哪個類的執行個體對象,該引用變量觸發的方法調用到底是哪個類中實作的方法,必須在程式運作期間才能決定。
11、面向對象程式設計的三大特點是什麼?
封裝、繼承、多态。
(1)封裝,即将描述同一個對象的屬性和方法定義在一個對象中。
(2)繼承,即父對象中的屬性和方法被子對象使用。
(3)多态,即同一個對象在不同情況下呈現不同的形态(注意,在 JavaScript中無多态”的概念)。多态有以下兩種形式。
重載,即同一方法名,根據傳入的參數不同,而執行不同操作。
重寫,即子對象在繼承父對象的屬性或方法後,重新定義一個新的屬性或方法以覆寫從父對象中繼承的屬性或方法。
12、面向對象開發的好處是什麼?
在代碼開發中,如果一些功能可能在某些網頁中是重複出現的,那麼完全可以把這部分功能封裝成一個對象,然後在多個地方進行調用,而不是每次遇到它的時候都重新書寫一次,以此來實作對資料或者方法的複用。
13、方法重載( Overload)與方法重寫( Override)的差別是什麼?
方法重載屬于編譯時的多态,根據傳遞的參數不同,執行不同的業務邏輯,得到不同的結果。方法重寫屬于運作時的多态,子類原型指向父類原型,子類重寫父類的方法,在調用子類方法的時候使用子類的方法,進而重寫父類中定義的方法。
14、如何判斷某個對象是否包含指定成員?
通過以下方式判斷。
(1)使用 obj. hasOwnProperty(" ")。
如果找到,傳回true;否則,傳回 false。
(2)使用“屬性名”in對象如果找到,傳回true;否則,傳回 false。
(3)直接使用ob屬性名作為判斷的條件,如下所示。
if (obj. demo === undefined)
若不包含,條件值為true;若包含,條件值為 false。
15、this通常指向誰?
在運作時,this關鍵字指向正在調用該方法的對象。
16、如何判斷屬性是自有屬性還是原型屬性?
方法如下
(1)要判斷自有屬性,使用 obj. hasOwn Property(“屬性名”)
(2)要判斷原型屬性,使用“屬性名” in obj&&!obj.hasOwn Property(“屬性名”)的形式。
17、實作對象的繼承有哪幾種方式?
有以下幾種方式
(1)修改對象的 _proto_,如下所示
Object.set Prototypeof(子對象,父對象)
(2)修改構造函數的原型對象,如下所示。
構造函數.prototype=對象
(3)使用原子繼承方法 Object.create(父對象[,{屬性清單}]),如下所示。
var demo = Object.create(obj)
本文完~