摘要:構(gòu)造函數(shù)的兩個(gè)特征函數(shù)內(nèi)部使用了,指向所要生成的對(duì)象實(shí)例。將一個(gè)空對(duì)象的指向構(gòu)造函數(shù)的屬性,這個(gè)對(duì)象就是要返回的實(shí)例對(duì)象。用面向?qū)ο箝_(kāi)發(fā)時(shí),把要生成的實(shí)例對(duì)象的特有屬性放到構(gòu)造函數(shù)內(nèi),把共有的方法放到構(gòu)造函數(shù)的里面。
JS中面向?qū)ο蟮母拍?/b>
面向?qū)ο驩OP是一種組織代碼結(jié)構(gòu)、實(shí)現(xiàn)功能過(guò)程的思維方式。它將真實(shí)世界各種復(fù)雜的關(guān)系,抽象為一個(gè)個(gè)對(duì)象,然后由對(duì)象之間的分工與合作,完成對(duì)真實(shí)世界的模擬。每一個(gè)對(duì)象都是功能中心,具有明確分工,可以完成接受信息、處理數(shù)據(jù)、發(fā)出信息等任務(wù)。
舉例:一本書(shū)、一輛汽車(chē)、一個(gè)人都可以是對(duì)象,一個(gè)數(shù)據(jù)庫(kù)、一張網(wǎng)頁(yè)、一個(gè)與遠(yuǎn)程服務(wù)器的連接也可以是對(duì)象。當(dāng)實(shí)物被抽象成對(duì)象,實(shí)物之間的關(guān)系就變成了對(duì)象之間的關(guān)系,從而就可以模擬現(xiàn)實(shí)情況,針對(duì)對(duì)象進(jìn)行編程。對(duì)象是單個(gè)實(shí)物的抽象,對(duì)象還是一個(gè)容器,封裝了屬性(property)和方法(method)。屬性是對(duì)象的狀態(tài),方法是對(duì)象的行為(完成某種任務(wù))。比如,我們可以把動(dòng)物抽象為animal對(duì)象,使用“屬性”記錄具體是那一種動(dòng)物,使用“方法”表示動(dòng)物的某種行為(奔跑、捕獵、休息等等)。
面向?qū)ο蟮膶?shí)現(xiàn)思路:把某個(gè)功能看成一個(gè)整體(對(duì)象),通過(guò)調(diào)用對(duì)象的某個(gè)方法來(lái)啟動(dòng)功能。在用的時(shí)候不去考慮這個(gè)對(duì)象內(nèi)部的實(shí)現(xiàn)細(xì)節(jié),在去實(shí)現(xiàn)這個(gè)對(duì)象細(xì)節(jié)的時(shí)候不用管誰(shuí)在調(diào)用。面向?qū)ο蟮姆椒ㄔ谇岸隧?yè)面中一般用來(lái)將重復(fù)的東西抽象化,便于復(fù)用和節(jié)省內(nèi)存。
面向?qū)ο蟮娜齻€(gè)要點(diǎn)封裝:就是將類(lèi)內(nèi)部的機(jī)制隱藏起來(lái),讓外界無(wú)法訪問(wèn),從而達(dá)到保護(hù)數(shù)據(jù)的目的。封閉一部分讓外界無(wú)法訪問(wèn),開(kāi)放一部分,通過(guò)開(kāi)放部分間接訪問(wèn)私有部分。可以用閉包來(lái)實(shí)現(xiàn)JS面向?qū)ο笾接袑傩苑庋b。
繼承:為了提高代碼的復(fù)用性,可以用繼承,將一個(gè)子類(lèi)繼承一個(gè)父類(lèi),這樣子類(lèi)就可以繼承父類(lèi)的屬性和方法,而不需要重新寫(xiě)一個(gè)類(lèi)中的屬性和方法。JavaScript的繼承方式是通過(guò)原型鏈來(lái)完成的。
多態(tài):多個(gè)子類(lèi)中雖然都具有同一個(gè)方法,但是這些子類(lèi)實(shí)例化的對(duì)象調(diào)用這些相同的方法后卻可以獲得不同的結(jié)果。
用傳統(tǒng)的面向?qū)ο笏季S,構(gòu)造實(shí)例的過(guò)程近似理解為:JS中object(對(duì)象)是某一個(gè)class(類(lèi))的實(shí)例,class可以理解成模具,object就是用模具制造出來(lái)的實(shí)物。
但JS中沒(méi)有類(lèi)的概念,只有構(gòu)造函數(shù)(函數(shù))、屬性的概念。很多語(yǔ)言中是由類(lèi)(class)構(gòu)造出實(shí)例對(duì)象,但JS中的對(duì)象不基于類(lèi)而構(gòu)建,而是基于構(gòu)造函數(shù)和原型鏈來(lái)構(gòu)建的。比如:var ccc={name:"penny"}這種寫(xiě)法是可行的,JS中本質(zhì)上是通過(guò)new Object()這個(gè)構(gòu)造函數(shù)來(lái)創(chuàng)建。對(duì)象是單個(gè)實(shí)物的抽象。通常需要一個(gè)模板,表示某一類(lèi)實(shí)物的共同特征,然后對(duì)象根據(jù)這個(gè)模板生成。JavaScript 語(yǔ)言使用構(gòu)造函數(shù)(constructor)作為對(duì)象的模板。所謂”構(gòu)造函數(shù)”,就是專(zhuān)門(mén)用來(lái)生成對(duì)象的函數(shù)。它提供模板,描述對(duì)象的基本結(jié)構(gòu)。一個(gè)構(gòu)造函數(shù),可以生成多個(gè)對(duì)象,這些對(duì)象都有相同的結(jié)構(gòu)。
通過(guò)類(lèi)構(gòu)建好比是上帝造人類(lèi),先定義好人的各屬性當(dāng)作模板,再創(chuàng)建人類(lèi)
不依賴(lài)類(lèi)構(gòu)建(函數(shù)式編程)好比是人進(jìn)化成人類(lèi),在進(jìn)化過(guò)程中不斷給人添加各種屬性形成人類(lèi)。
構(gòu)造函數(shù)的兩個(gè)特征:
[1]函數(shù)內(nèi)部使用了this,指向所要生成的對(duì)象實(shí)例。
[2]必須用new命令調(diào)用生成對(duì)象實(shí)例
new運(yùn)算符接受一個(gè)函數(shù)及其參數(shù)作為構(gòu)造器,根據(jù)傳入?yún)?shù)來(lái)創(chuàng)建相同類(lèi)型但值不同的實(shí)例對(duì)象。new命令的作用,就是執(zhí)行構(gòu)造函數(shù),返回一個(gè)實(shí)例對(duì)象。
new Function()的三個(gè)步驟:
1.創(chuàng)建類(lèi)的實(shí)例。將一個(gè)空對(duì)象的__proto__指向構(gòu)造函數(shù)的prototype屬性,這個(gè)對(duì)象就是要返回的實(shí)例對(duì)象。
2.初始化實(shí)例。將參數(shù)傳入構(gòu)造函數(shù)并執(zhí)行構(gòu)造函數(shù),因?yàn)闃?gòu)造函數(shù)內(nèi)部的this指向的是由構(gòu)造函數(shù)生成的實(shí)例。針對(duì)this的操作都會(huì)發(fā)生在這個(gè)空對(duì)象上,所以通過(guò)this,實(shí)例可繼承構(gòu)造函數(shù)的屬性和方法。
3.返回實(shí)例。
構(gòu)造函數(shù)之所以叫“構(gòu)造函數(shù)”,就是因?yàn)闃?gòu)造函數(shù)操作一個(gè)空對(duì)象(即this指向的實(shí)例對(duì)象),將其“構(gòu)造”為需要的樣子。
普通函數(shù)用new調(diào)用時(shí),因?yàn)槠胀ê瘮?shù)內(nèi)部沒(méi)有this,所以使用new命令執(zhí)行后返回的是一個(gè)空對(duì)象。new運(yùn)算符接受一個(gè)函數(shù)及其參數(shù)作為構(gòu)造器,根據(jù)傳入?yún)?shù)來(lái)創(chuàng)建相同類(lèi)型但值不同的實(shí)例對(duì)象。new命令的作用,就是執(zhí)行構(gòu)造函數(shù),返回一個(gè)實(shí)例對(duì)象。
new Function()的三個(gè)步驟:
1.創(chuàng)建類(lèi)的實(shí)例。將一個(gè)空對(duì)象的__proto__指向構(gòu)造函數(shù)的prototype屬性,這個(gè)對(duì)象就是要返回的實(shí)例對(duì)象。
2.初始化實(shí)例。將參數(shù)傳入構(gòu)造函數(shù)并執(zhí)行構(gòu)造函數(shù),因?yàn)闃?gòu)造函數(shù)內(nèi)部的this指向的是由構(gòu)造函數(shù)生成的實(shí)例。針對(duì)this的操作都會(huì)發(fā)生在這個(gè)空對(duì)象上,所以通過(guò)this,實(shí)例可繼承構(gòu)造函數(shù)的屬性和方法。
3.返回實(shí)例。
構(gòu)造函數(shù)之所以叫“構(gòu)造函數(shù)”,就是因?yàn)闃?gòu)造函數(shù)操作一個(gè)空對(duì)象(即this指向的實(shí)例對(duì)象),將其“構(gòu)造”為需要的樣子。普通函數(shù)用new調(diào)用時(shí),因?yàn)槠胀ê瘮?shù)內(nèi)部沒(méi)有this,所以使用new命令執(zhí)行后返回的是一個(gè)空對(duì)象。
this總是返回一個(gè)對(duì)象,簡(jiǎn)單說(shuō),就是返回屬性或方法“當(dāng)前”所在的對(duì)象。隨著函數(shù)使用場(chǎng)景的不同,this的值會(huì)發(fā)生變化可近似理解成this指向的是函數(shù)當(dāng)前的運(yùn)行環(huán)境。但是有一個(gè)總的原則,this指向的是,調(diào)用函數(shù)的那個(gè)對(duì)象。
函數(shù)調(diào)用時(shí)的this
函數(shù)直接調(diào)用時(shí)是在全局作用域下調(diào)用的,瀏覽器中的全局作用域是window,this指向window
function fn1(){ console.log(this); //指向window } fn1();
嵌套函數(shù)調(diào)用時(shí)的this
函數(shù)嵌套產(chǎn)生的內(nèi)部函數(shù)的this不指向其父函數(shù),仍然是指向全局變量。
function fn0(){ function fn(){ console.log(this); //這里的this在調(diào)用fn0時(shí)依然指向全局window } fn(); } fn0();
setTimeout、setInterval中的this
延時(shí)函數(shù)執(zhí)行時(shí)是在全局作用域下執(zhí)行,所以this依然指向window
構(gòu)造函數(shù)調(diào)用時(shí)內(nèi)部的this
調(diào)用構(gòu)造函數(shù)時(shí),構(gòu)造函數(shù)內(nèi)的this指向的是構(gòu)造函數(shù)創(chuàng)建的實(shí)例對(duì)象。
對(duì)象的方法中的this
函數(shù)可以作為一個(gè)對(duì)象的屬性,此時(shí)該函數(shù)被稱(chēng)為該對(duì)象的方法。當(dāng)函數(shù)作為一個(gè)對(duì)象的方法調(diào)用時(shí),這個(gè)函數(shù)內(nèi)部的this指向調(diào)用該函數(shù)的對(duì)象。
var obj1 = { name: "Byron", fn : function(){ console.log(this); } }; obj1.fn(); //調(diào)用后this指向obj1
嵌套對(duì)象調(diào)用時(shí)this指向最近那一層的對(duì)象,嵌套函數(shù)調(diào)用時(shí)this指向window而不指向最近那層函數(shù)
var a = { p: "Hello", b: { m: function() { console.log(this.p); } } }; a.b.m() // undefined
DOM對(duì)象事件綁定,事件處理函數(shù)的this
在事件處理程序中this代表事件源DOM對(duì)象。低版本IE的bug會(huì)指向window
document.addEventListener("click", function(e){ console.log(this); //指向DOM對(duì)象 var _document = this; setTimeout(function(){ console.log(this); //指向window console.log(_document); }, 200); }, false);原型鏈
“原型鏈”的作用是,讀取對(duì)象的某個(gè)屬性時(shí),JavaScript 引擎先尋找對(duì)象本身的屬性(同名屬性會(huì)優(yōu)先讀取自身屬性),如果找不到,就通過(guò)__proto__到它的原型去找,如果還是找不到,就通過(guò)原型的__proto__到原型的原型去找。如果直到最頂層的Object.prototype還是找不到,則返回null。
__proto__屬性是瀏覽器的內(nèi)部屬性,應(yīng)盡量避免使用,建議使用
Object.getPrototype(obj)來(lái)獲取對(duì)象的原型對(duì)象
Object.setPrototypeOf(obj1,obj2)修改對(duì)象的原型對(duì)象。
獲取一個(gè)對(duì)象的原型對(duì)象有三種方法:
obj.__proto__ 不靠普,ES6規(guī)范僅瀏覽器部署,其他環(huán)境沒(méi)有部署
obj.constructor.prototype 不靠普,obj.constructor.prototype手動(dòng)改變后如果不修正constructor會(huì)導(dǎo)致obj.constructor.prototype指向不準(zhǔn)確
Object.getPrototypeOf(obj) 推薦使用
原型鏈的特性
【1】任何對(duì)象上都有__proto__這個(gè)屬性,指向創(chuàng)建該對(duì)象的構(gòu)造函數(shù)的prototype屬性(原型對(duì)象)。
【2】用面向?qū)ο箝_(kāi)發(fā)時(shí),把要生成的實(shí)例對(duì)象的特有屬性放到構(gòu)造函數(shù)內(nèi),把共有的方法放到構(gòu)造函數(shù)的prototype里面。只要修改構(gòu)造函數(shù)的原型對(duì)象prototype,所有構(gòu)造函數(shù)生成的實(shí)例對(duì)象上繼承來(lái)自原型對(duì)象prototype的方法或者屬性都會(huì)改變。
【3】原型鏈:任何對(duì)象都是由一個(gè)更高級(jí)的構(gòu)造函數(shù)創(chuàng)建來(lái)的。比如對(duì)象是由object函數(shù)創(chuàng)建來(lái)。prototype是函數(shù)的屬性,__proto__隱式原型是對(duì)象(object)的屬性。由于JS中函數(shù)也是對(duì)象,所以函數(shù)上也有__proto__屬性。對(duì)象的__proto__指向這個(gè)對(duì)象的構(gòu)造函數(shù)的prototype
【4】任何函數(shù)都有prototype屬性即原型對(duì)象,原型對(duì)象默認(rèn)有constructor屬性,指向原型對(duì)象prototype所在的構(gòu)造函數(shù),即表示這個(gè)原型對(duì)象屬于哪個(gè)構(gòu)造函數(shù)(類(lèi)型,js無(wú)類(lèi)型的概念)。constructor屬性定義在prototype對(duì)象上面,可以被所有實(shí)例對(duì)象繼承。修改原型對(duì)象時(shí),一般要同時(shí)校正constructor屬性的指向,建議用給原型對(duì)象添加方法的形式修改原型對(duì)象,而不是完全覆蓋原型對(duì)象。
C.prototype.method1 = function (...) { ... };
instanceof
instanceof 判斷一個(gè)對(duì)象(不能判斷原始類(lèi)型值)是不是某個(gè)構(gòu)造函數(shù)(類(lèi))的實(shí)例,返回布爾值,通過(guò)檢查原型鏈來(lái)實(shí)現(xiàn)判斷。instanceof對(duì)整個(gè)原型鏈上的對(duì)象都有效,因此同一個(gè)實(shí)例對(duì)象,可能會(huì)對(duì)多個(gè)構(gòu)造函數(shù)都返回true。
var d = new Date(); d instanceof Date // true d instanceof Object // true //instanceof可以用來(lái)判斷值的類(lèi)型 var x = [1, 2, 3]; var y = {}; x instanceof Array // true y instanceof Object // true原型圖示例
function People (name){ this.name = name; this.sayName = function(){ console.log("my name is:" + this.name); } } People.prototype.walk = function(){ console.log(this.name + " is walking"); } var p1 = new People("饑人谷"); var p2 = new People("前端");
圖片轉(zhuǎn)載自知乎
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/108098.html
摘要:很多情況下,通常一個(gè)人類(lèi),即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類(lèi)是相似對(duì)象的描述,稱(chēng)為類(lèi)的定義,是該類(lèi)對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類(lèi)的實(shí)體化形成的對(duì)象。一類(lèi)的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類(lèi)的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個(gè)人類(lèi),即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類(lèi)是相似對(duì)象的描述,稱(chēng)為類(lèi)的定義,是該類(lèi)對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類(lèi)的實(shí)體化形成的對(duì)象。一類(lèi)的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類(lèi)的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個(gè)人類(lèi),即創(chuàng)建了一個(gè)具體的對(duì)象。對(duì)象就是數(shù)據(jù),對(duì)象本身不包含方法。類(lèi)是相似對(duì)象的描述,稱(chēng)為類(lèi)的定義,是該類(lèi)對(duì)象的藍(lán)圖或原型。在中,對(duì)象通過(guò)對(duì)類(lèi)的實(shí)體化形成的對(duì)象。一類(lèi)的對(duì)象抽取出來(lái)。注意中,對(duì)象一定是通過(guò)類(lèi)的實(shí)例化來(lái)的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:是完全的面向?qū)ο笳Z(yǔ)言,它們通過(guò)類(lèi)的形式組織函數(shù)和變量,使之不能脫離對(duì)象存在。而在基于原型的面向?qū)ο蠓绞街?,?duì)象則是依靠構(gòu)造器利用原型構(gòu)造出來(lái)的。 JavaScript 函數(shù)式腳本語(yǔ)言特性以及其看似隨意的編寫(xiě)風(fēng)格,導(dǎo)致長(zhǎng)期以來(lái)人們對(duì)這一門(mén)語(yǔ)言的誤解,即認(rèn)為 JavaScript 不是一門(mén)面向?qū)ο蟮恼Z(yǔ)言,或者只是部分具備一些面向?qū)ο蟮奶卣?。本文將回歸面向?qū)ο蟊疽猓瑥膶?duì)語(yǔ)言感悟的角度闡述為什...
摘要:用代碼可以這樣描述安全到達(dá)國(guó)外面向過(guò)程既然說(shuō)了面向?qū)ο?,那么與之對(duì)應(yīng)的就是面向過(guò)程。小結(jié)在這篇文章中,介紹了什么是面向?qū)ο蠛兔嫦蜻^(guò)程,以及中對(duì)象的含義。 這是 javascript 面向?qū)ο蟀鎵K的第一篇文章,主要講解對(duì)面向?qū)ο笏枷氲囊粋€(gè)理解。先說(shuō)說(shuō)什么是對(duì)象,其實(shí)這個(gè)還真的不好說(shuō)。我們可以把自己當(dāng)成一個(gè)對(duì)象,或者過(guò)年的時(shí)候相親,找對(duì)象,那么你未來(lái)的老婆也是一個(gè)對(duì)象。我們就要一些屬性,比...
摘要:之前,本質(zhì)上不能算是一門(mén)面向?qū)ο蟮木幊陶Z(yǔ)言,因?yàn)樗鼘?duì)于封裝繼承多態(tài)這些面向?qū)ο笳Z(yǔ)言的特點(diǎn)并沒(méi)有在語(yǔ)言層面上提供原生的支持。所以在中出現(xiàn)了等關(guān)鍵字,解決了面向?qū)ο笾谐霈F(xiàn)了問(wèn)題。 ES6之前,javascript本質(zhì)上不能算是一門(mén)面向?qū)ο蟮木幊陶Z(yǔ)言,因?yàn)樗鼘?duì)于封裝、繼承、多態(tài)這些面向?qū)ο笳Z(yǔ)言的特點(diǎn)并沒(méi)有在語(yǔ)言層面上提供原生的支持。但是,它引入了原型(prototype)的概念,可以讓我們以...
閱讀 3287·2021-11-23 09:51
閱讀 3629·2021-11-09 09:46
閱讀 3790·2021-11-09 09:45
閱讀 3019·2019-08-29 17:31
閱讀 1909·2019-08-26 13:39
閱讀 2773·2019-08-26 12:12
閱讀 3680·2019-08-26 12:08
閱讀 2285·2019-08-26 11:31