溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么理解JavaScript中的面向?qū)ο?/h1>
發(fā)布時(shí)間:2021-11-20 14:09:42 來(lái)源:億速云 閱讀:106 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要講解了“怎么理解JavaScript中的面向?qū)ο蟆?,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“怎么理解JavaScript中的面向?qū)ο蟆卑桑?/p>

  JavaScript 是面向?qū)ο蟮?。但是不少人?duì)這一點(diǎn)理解得并不全面。
  在 JavaScript 中,對(duì)象分為兩種。一種可以稱為“普通對(duì)象”,就是我們所普遍理解的那些:數(shù)字、日期、用戶自定義的對(duì)象(如:{})等等。
  還有一種,稱為“方法對(duì)象”,就是我們通常定義的 function。你可能覺(jué)得奇怪:方法就是方法,怎么成了對(duì)象了?但是在 JavaScript 中,方法的確是被當(dāng)成對(duì)象來(lái)處理的。下面是一個(gè)簡(jiǎn)單的例子:
  function func() {alert('Hello!');}
  alert(func.toString());
  在這個(gè)例子中,func 雖然是作為一個(gè)方法定義的,但它自身卻包含一個(gè) toString 方法,說(shuō)明 func 在這里是被當(dāng)成一個(gè)對(duì)象來(lái)處理的。更準(zhǔn)確的說(shuō),func 是一個(gè)“方法對(duì)象”。下面是例子的繼續(xù):
  func.name = “I am func.”;
  alert(func.name);
  我們可以任意的為 func 設(shè)置屬性,這更加證明了 func 就是一個(gè)對(duì)象。那么方法對(duì)象和普通對(duì)象的區(qū)別在哪里呢?首先方法對(duì)象當(dāng)然是可以執(zhí)行的,在它后面加上一對(duì)括號(hào),就是執(zhí)行這個(gè)方法對(duì)象了。
  func();
  所以,方法對(duì)象具有二重性。一方面它可以被執(zhí)行,另一方面它完全可以被當(dāng)成一個(gè)普通對(duì)象來(lái)使用。這意味著什么呢?這意味著方法對(duì)象是可以完全獨(dú)立于其他對(duì)象存在的。這一點(diǎn)我們可以同 Java 比較一下。在 Java 中,方法必須在某一個(gè)類(lèi)中定義,而不能單獨(dú)存在。而 JavaScript 中就不需要。
  方法對(duì)象獨(dú)立于其他方法,就意味著它能夠被任意的引用和傳遞。下面是一個(gè)例子:
  function invoke(f) {
  f();
  }
  invoke(func);
  將一個(gè)方法對(duì)象 func 傳遞給另一個(gè)方法對(duì)象 invoke,讓后者在適當(dāng)?shù)臅r(shí)候執(zhí)行 func。這就是所謂的“回調(diào)”了。另外,方法對(duì)象的這種特殊性,也使得 this 關(guān)鍵字不容易把握。這方面相關(guān)文章不少,這里不贅述了。
  除了可以被執(zhí)行以外,方法對(duì)象還有一個(gè)特殊的功用,就是它可以通過(guò) new 關(guān)鍵字來(lái)創(chuàng)建普通對(duì)象。
  話說(shuō)每一個(gè)方法對(duì)象被創(chuàng)建時(shí),都會(huì)自動(dòng)的擁有一個(gè)叫 prototype 的屬性。這個(gè)屬性并無(wú)什么特別之處,它和其他的屬性一樣可以訪問(wèn),可以賦值。不過(guò)當(dāng)我們用 new 關(guān)鍵字來(lái)創(chuàng)建一個(gè)對(duì)象的時(shí)候,prototype 就起作用了:它的值(也是一個(gè)對(duì)象)所包含的所有屬性,都會(huì)被復(fù)制到新創(chuàng)建的那個(gè)對(duì)象上去。下面是一個(gè)例子:
  func.prototype.name=”prototype of func”;
  var f = new func();
  alert(f.name);
  執(zhí)行的過(guò)程中會(huì)彈出兩個(gè)對(duì)話框,后一個(gè)對(duì)話框表示 f 這個(gè)新建的對(duì)象從 func.prototype 那里拷貝了 name 屬性。而前一個(gè)對(duì)話框則表示 func 被作為方法執(zhí)行了一遍。你可能會(huì)問(wèn)了,為什么這個(gè)時(shí)候要還把 func 執(zhí)行一遍呢?其實(shí)這個(gè)時(shí)候執(zhí)行 func,就是起“構(gòu)造函數(shù)”的作用。為了形象的說(shuō)明,我們重新來(lái)一遍:
  function func() {
  this.name=”name has been changed.”
  }
  func.prototype.name=”prototype of func”;
  var f = new func();
  alert(f.name);
  你就會(huì)發(fā)現(xiàn) f 的 name 屬性不再是"prototype of func",而是被替換成了"name has been changed"。這就是 func 這個(gè)對(duì)象方法所起到的“構(gòu)造函數(shù)”的作用。所以,在 JavaScript 中,用 new 關(guān)鍵字創(chuàng)建對(duì)象是執(zhí)行了下面三個(gè)步驟的:
  創(chuàng)建一個(gè)新的普通對(duì)象;
  將方法對(duì)象的 prototype 屬性的所有屬性復(fù)制到新的普通對(duì)象中去。
  以新的普通對(duì)象作為上下文來(lái)執(zhí)行方法對(duì)象。
  對(duì)于“new func()”這樣的語(yǔ)句,可以描述為“從 func 創(chuàng)建一個(gè)新對(duì)象”??傊琾rototype 這個(gè)屬性的唯一特殊之處,就是在創(chuàng)建新對(duì)象的時(shí)候了。
  那么我們就可以利用這一點(diǎn)。比如有兩個(gè)方法對(duì)象 A 和 B,既然從 A 創(chuàng)建的新對(duì)象包含了所有 A.prototype 的屬性,那么我將它賦給 B.prototype,那么從 B 創(chuàng)建的新對(duì)象不也有同樣的屬性了?寫(xiě)成代碼就是這樣:
  
  A.prototype.hello = function(){alert('Hello!');}
  B.prototype = new A();
  new B().hello();
  這就是 JavaScript 的所謂“繼承”了,其實(shí)質(zhì)就是屬性的拷貝,這里利用了 prototype 來(lái)實(shí)現(xiàn)。如果不用 prototype,那就用循環(huán)了,效果是一樣的。所謂“多重繼承”,自然就是到處拷貝了。
  JavaScript 中面向?qū)ο蟮脑恚褪巧厦孢@些了。自始至終我都沒(méi)提到“類(lèi)”的概念,因?yàn)?JavaScript 本來(lái)就沒(méi)有“類(lèi)”這個(gè)東西。面向?qū)ο罂梢詻](méi)有類(lèi)嗎?當(dāng)然可以。先有類(lèi),然后再有對(duì)象,這本來(lái)就不合理,因?yàn)轭?lèi)本來(lái)是從對(duì)象中歸納出來(lái)的,先有對(duì)象再有類(lèi),這才合理。像下面這樣的:
  var o = {}; // 我發(fā)現(xiàn)了一個(gè)東西。
  o.eat = function(){return "I am eating."} // 我發(fā)現(xiàn)它會(huì)吃;
  o.sleep = function(){return "ZZZzzz..."} // 我發(fā)現(xiàn)它會(huì)睡;
  o.talk = function(){return "Hi!"} // 我發(fā)現(xiàn)它會(huì)說(shuō)話;
  o.think = function(){return "Hmmm..."} // 我發(fā)現(xiàn)它還會(huì)思考。
  var Human = new Function(); // 我決定給它起名叫“人”。
  Human.prototype = o; // 這個(gè)東西就代表了所有“人”的概念。
  var h = new Human(); // 當(dāng)我發(fā)現(xiàn)其他同它一樣的東西,
  alert(h.talk()) // 我就知道它也是“人”了!

感謝各位的閱讀,以上就是“怎么理解JavaScript中的面向?qū)ο蟆钡膬?nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)怎么理解JavaScript中的面向?qū)ο筮@一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)
AI