javascript 高級--面向對象

?? 高級的階段,我們要理解其中的計算機運行的概念。設計計算機編程的時候,我們程序員賦給計算機邏輯運算體系。這種體系的嚴謹性和指向性讓程序員給予很大的挑戰。javascript這門編程語言是基于對象的語言,也是弱語言腳本語言。現在很多網上的博客大多數認為是面向對象的語言。面向對象的編程語言需要有 類 對象實例 封裝? 繼承? 多態 這幾個特征。 javascript 沒有類的概念。也不是面向對象的編程語言。但可以通過字面量 工廠方法 構造函數的方法來創建對象。實現面向對象的要素和功能。什么為類的概念呢?就是具有共同的特征的名稱的集合。其他的編程語言大多數是有類的概念的。所以javascipt 是基于對象的語言。但是可以通過很多方法來創建對象。

1:通過字面量來創建我們解決問題的對象。

var person = {??? //?? 我們創建了一個人的對象實例,我們計算機系統運行的時候,需要對象和邏輯運算體系。解決問題??? 就是來創建問題本身所需要的對象。面向對象就是讓我們來提高解決問題的效率。而不是面向過程那樣復雜。創建解決問題的對象。當然,可以跟據業務的需要來分析對象的創建的范圍

???? name :? "小明",???? //? 對象的屬性 是對象自身帶有的,當然,我們也可以自己的需要來給對象添加屬性。屬性名+冒號+屬性值。屬性值是可以任意數據類型。是數值和數組 也可以是字符串。是可以通過對象點屬性的 是屬性值。逗號是提示下面也有屬性的。這是通過字面量的創建對象的語法格式。如果是最后的屬性名的話,不用加逗號的。加的話會報錯。

???? age :???? 18,

eatFood : function () {?? //? 這是對象的方法。也就是對象的所具有的功能。可以解決問題的關鍵環節。當然,屬性的作用是提供我們解決問題的材料。也是不可以避免的。屬性+方法是我們來解決問題的完整體系。方法是函數的形式來創建的。

?????? alert("吃飯");??????

}

}
// 通過工廠的方法來創建對象。

function? person () {

???? var person = {};??? // 創建一個模板 ,來大批量的生產同一的對象。

???? person.name = "小明";?? //給予對象的屬性賦值。

??? person.age =? 18;

?? person.eatFunction? =? function () {??????????? //? 給對象創建方法。?

??? alert("吃食物")???? //? 在工廠方法里面??? js引擎沒有創造原生對象。也不具備原生對象的相關知識。

??? }

}

//? 通過構造函數的方法創建對象。

function person (name,age)? {??????

?this.name = name;???? // 通過構造函數來創造對象,是個范本。是具有相同的屬性和方法。用this指針可以幫助我們優化代碼,因為構造函數也是在調用的時候來有意義,this指針也是在具體的對象實例中來指向誰。誰調用i就指向誰。這也是封裝的含義。this只能用在函數體當中。this就是指向new 開辟的內存空間。所以我們用構造函數來創建對象,對象的實例就必然用new來開辟空間 調用函數,然后再傳參數。完成解決問題的整個過程。 注意:傳參數時,我們要考慮參數的數據類型。因為是屬性值的 ?在構造函數時,我們給予的參數是變量的。用變量來保存值。傳參數時,我們可以是任意數據類型。如果是變量的話。要么是變量的轉化為字符串,就是加雙引號和單引號。要么是變量保存的值是字符串也可以。

?this.age? =? age;??

this.eatFunction = function ()? {

? alert("吃食物") ? ?

?? }

}

var per1? = new person ("name",age) // ?注意參數的類型。看變量保存的值。

我們創建了對象的實例后,我們知道對象的屬性有很多,我們怎么樣去訪問對象的屬性呢?我們是不是可以類比的數組的遍歷的方式來訪問對象的屬性呢?// 通過for..in.循環的來訪問。

答案是可以的。訪問單個的屬性直接調用用 對象 點 屬性就可以了。就可以拿到這個屬性的值。

for (var protopy ?in obj){ ?

console.log(obj["protopy"]) ?// ? 訪問對象的屬性用兩種方法 :1: 是 對象名+“.” 屬性名。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2:? 是 對象名+[]? 中括號是里面是字符串的類型。或變量的保存值。? 所以,我們可以擴展一下。在構造函數中,在js引擎中,編譯的過程中,會自動創建原型對象,就是天生的原型。是在系統中隱式的創建。為什么要創建原型的對象呢?因為在構造函數中,優點很多,比如是特征化,把對象的屬性和方法賦值在this 指針上 用this指針直接點屬性和方法就可以了。在封裝函數時,我們也可以用this指針來指向調用的函數對象。比較方便簡化。但是會占內存。因為我們在構造函數時,我們就會造成內存占用。所以,用原生對象來保存一些公有的方法和屬性。可以讓構造函數的對象實例來訪問,拿到的共同擁有的方法。我們用構造函數給予原生對象一些方法來供構造函數的對象實例使用。我們用這個屬性 prototype 來訪問原生對象。這個屬性是一個指針的功能,可以幫我們找到我們需要的對應的原生對象。當然,原生對象也需要個指針的功能來指向構造函數。就constructor 的屬性來指向構造函數。這樣,就保證了語言的嚴謹性。

}

function creatObject () { ?

this.name = name;

this.age = age;

}

creatObject.prototype.sayHi = function () { ?

alert() ?// ?所需要的方法 ? 原生對象的方法。代碼塊。

}

var per1 = new creatObject ("xiaom",20);

per1.sayHi(); ?// ?調用原型的方法。

注意:我們需要明白的不能通過_proto_來訪問原生對象的。在語法上是禁止的。我們把構造函數看做是老大,對象實例是老二 也是說,對象實例可以通過查找對象屬性的方法來調用原生對象的屬性和方法。當然,改變老大的值,會間接改變老二的值。在高級的語法中,我們經常會犯這樣的錯,邏輯層次的混亂,對象的亂用。所以,我們要分清指向的對象。

原生對象的屬性和方法是添加在自定義的構造函數 可以供構造函數的對象實例來使用。

構造函數的對象的實例, 如果有自身的屬性和方法,在訪問的時候(注意:只有在讀取的時候,對象的實例可以自身用,不用向原生對象拿值。)如果是沒有的屬性和方法,對象實例會向原生對象拿值。如果也沒有,原生對象會向Object 拿值,如果也沒有,就會語法報錯。所以,我們可以把方法和屬性掛載原型上或者是Object. ?比如,我們可以封裝函數。

Object.prototype.isPrototype = function (arrt,obj) { ?

? ? ? ? ? ? ? ?if(!(arrt in obj)) { ? ? ? // 我們來更加理解下if,,else 判斷語句的用法。if 下的語句是為真的情況,也就是為 true 的情況。所以,遇見判斷為布爾類型的值時,就可以直接寫在if 語句上了。else是為false時,來執行else中的語句。if 和邏輯非(!)聯合就可以包括所有的布爾判斷類型。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return null

? ? ? ? ?}else if ?(obj.hasOwnProperty(arrt)) ?{ ? // ?為true 時是實例對象的。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return ture

? ? ? ?}else ?{ ? ??

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return false

? ? ? ? ? }

? ?}

// 這樣就掛載在對象的根上了。Object ?可以調用了。

// ?在用原生對象掛載方法時,每當this指針的對象實例調用原生對象的函數時,都會重新寫一次,在內存上造成浪費。所以就利用判斷來避免這樣的內存占用。

function person (name,age,sex) { ?

this.name =name;

this.age = age;

this.sex = sex;

? ?if (typeOf this.sayHi != "function") { ? // 比較是判斷的類型。function 是個字符串而不是變量。

? ? ? ? ? ?person.prototype.sayHI = function () { ?

? ? ? ? ? ?alert (this.name+"hello")

? ? ? ? ? ?}

? ? ? }

}

var per1 = new person("小明",18,"男");

var per2 = new person("小紅",18,"女");

per1.sayHi(); ?//?

per2.sayHi(); //

我們既然可以在實例對象和原型對象中有屬性和方法,我們這么樣去判斷這個屬性是實例的還是原型的?我們可以通過hasOwnPrototype 來判斷實例有這個屬性。還要用in來判斷是個有沒有這個屬性。二者可以聯合可以判斷。先判斷 in 再判斷 hasOwnPrototype的用法。

今天我們學習的是繼承。繼承是面向對象的重要內容。我們對于繼承的理解是生活中的父子繼承遺產關系。也是生物學中的遺傳基因。計算機編程也是生活中的設計者。計算機我們也會有繼承關系。父級與子級的繼承關系。面向對象的繼承也是有繼承樹來實現的。我們創建對象時,我們通過需要構造函數來創建類的概念。既然是類,我們有一些共同的屬性,和方法。我們之前的做法是,共同的屬性用在構造函數里,共同的方法是通過原型來掛載方法。來節省空間。讓大家的對象實例都利用起來方法。比如舉個例子:

// ?我們先構造函數來創造對象。(其實是類的概念)

function person () {

this.name = name;

this.age = age; ? ? ? ?// 這些都是屬性。類的特征。

this.heigth = heigth;

this.sayHi = function () ?{  // ?這是個方法。我們在構造函數中去創造。這個對象的實例就可以調用了。但是通過new 來開辟空間,用this 指針來指向具體的對象實例。這樣每個不同的實例都會通過new來開辟空間,內存將會占用。所以,我們將一些共同的方法掛載在原型上。這樣我們就可以讓不同的實例通過自己的內部指針來_proto_ 來訪問查找原型對象。來調取原型對象的方法。這樣就大大的節約空間了。提高我們的效率。

alert("hello")

  }

}

person.prototype.eatFood = function ( ) { ??

? alert("吃飯了"); ?// 這就是把共同的方法掛載在原型上。

}

繼承的方法,我們需要最低倆個對象。父級和子級

function createAnimal () {?

this.name = name;

this.age = age;

}

createAnimal.prototype.eatFood ?= ?function ( ) ?{?

alert("吃食物");

}

function creatPerson () {

this.gener = gener;

this.height = heigth ;

// ? 我們來繼承父級的name和age 屬性 用call() 和apply()來創建。call()和 apply ()可以來改變this指針的指向。第一個參數就是改變this指針的指向對象和驅動父級構造函數。后面可以傳參,這樣我們就可以利用這兩個特性來為繼承服務。

createAnima.call(this,name,age) ?// 改變this的指針指向子級。然后傳參,拿到我們需要取的值。

?}

var per = new creatPerson("xiaozhang",18)

per.eatFood ();

2 : 通過原生鏈來繼承。

function createAnimal () {

this.name = name;

this.age = age;

}

createAnimal.prototype.eatFood ?= ?function ( ) ?{

alert("吃食物");

}

function creatPerson () {

this.gener = gener;

this.height = heigth ;

// 我們通過原生鏈來繼承。原理就是父級的對象實例來替換子級的原生對象。通過內部指針_proto_來形成原生鏈來繼承父級的屬性和方法。

creatPerson.prototype = new ?createAnimal ("xiaoming",17); ?// 只有在這個地方給父級實例對象傳相對應的屬性參數。不然,沒有機會了。但是,我們的參數就是固定了,不夠靈活了。

creatPerson.prototype.constructor = creatPerson;

}

var per = new creatPerson("xiaoming",17)

per.eatFood();

3 通過原生原型和改變this指針來組合繼承。

function createAnimal (name,age) {

this.name = name;

this.age = age;

}

createAnimal.prototype.eatFood ?= ?function ( ) ?{

alert("吃食物");

}

function creatPerson (name,age,gener) {

this.gener = gener;

this.height = heigth ;

createAnimal.call(this,name,age)

creatPerson.prototype = new createAnimal(); ??

creatPerson.prototype.constructor = creatPerson;

creatPerson.prototype.run = function () {?

alert("跑步")?

? ?}

}

var per = new creatPerson("xingmong",20,"man")

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,016評論 2 375

推薦閱讀更多精彩內容