classjs的理解,js class語法

本文目錄一覽:

js中如何定義class,如何擴展prototype?

js沒有class的概念,可以模擬對象.function MyObject() {}上面就是一個對象,你也可以理解為一個ClassMyObject.prototype.show = function () { alert(); }為原型擴展一個叫做show的方法new MyObject().show();調用這個方法.

html 中 id 和 class js

你說的是id的唯一性吧,即一個div只會有一個id來定義其樣式;相對於class而言,一個div可以有多個class來定義其樣式。

你的兩種寫法都是正確的,你的第一種寫法毋庸置疑是對的,第二種是兩個div同時使用一種樣式一個id(而不是一個div用多個id),所以也是對的。

看來你是初學者,有問題我很樂意幫你。

如何理解Javascript中類和對象這兩個概念

在說這個話題之前,我想先說幾句題外話:最近偶然碰到有朋友問我「hoisting」的問題。即在js里所有變數的聲明都是置頂的,而賦值則是在之後發生的。可以看看這個例子:

var a = ‘global’;

(function () {

alert(a);

var a = ‘local’;

})();

大家第一眼看到這個例子覺得輸出結果是什麼?『global』?還是『local』?其實都不是,輸出的是undefined,不用迷惑,我的題外話就是為了講這個東西的。

其實很簡單,看一看JavaScript運行機制就會明白。我們可以把這種現象看做「預聲明」。但是如果稍微深究一下,會明白得更透徹。

這裡其實涉及到對象屬性綁定機制。因為所有JavaScript函數都是一個對象。在函數里聲明的變數可以看做這個對象的「類似屬性」。對象屬性的綁定在語言里是有分「早綁定」和「晚綁定」之分的。

【早綁定】

是指在實例化對象之前定義其屬性和方法。解析程序時可以提前轉換為機器代碼。通常的強類型語言如C++,java等,都是早綁定機制的。而JavaScript不是強類型語言。它使用的是「晚綁定」機制。

【晚綁定】

是指在程序運行前,無需檢查對象類型,只要檢查對象是否支持特性和方法即可。可以在綁定前對對象執行大量操作而不受任何懲罰。

上面代碼出現的「預聲明」現象,我們大可用「晚綁定」機制來解釋。在函數的作用域中,所有變數都是「晚綁定」的。 即聲明是頂級的。所以上面的代碼和下面的一致:

var a = ‘global’;

(function () {

var a;

alert(a);

a = ‘local’;

})();

在alert(a)之前只對a作了聲明而沒有賦值。所以結果可想而知。

!– 題外話到此結束 —

RT:本文要說的是,在JavaScript里,我所知道的幾種定義類和對象的方式:! — 聲明:以下內容大部分來自《JavaScript高級程序設計》,只是個人敘述方式不同而已 —

【直接量方式】

使用直接量構建對象是最基礎的方式,但也有很多弊端。

var Obj = new Object;

Obj.name = ‘sun’;

Obj.showName = function() {

alert(‘this.name’);

}

我們構建了一個對象Obj,它有一個屬性name,一個方法showName。但是如果我們要再構建一個類似的對象呢?難道還要再重複一遍?

NO!,我們可以用一個返回特定類型對象的工廠函數來實現。就像工廠一樣,流水線的輸出我們要的特定類型結果。

【工廠方式】

function createObj(name) {

var tempObj = new Object;

tempObj.name = name;

tempObj.showName = function () {

alert(this.name);

};

return tempObj;

}

var obj1 = createObj(‘obj_one’);

var obj2 = createObj(‘obj_two’);

這種工廠函數很多人是不把他當做構建對象的一種形式的。一部分原因是語義:即它並不像使用了運算符new來構建的那麼正規。還有一個更大的原因,是因為這個工廠每次產出一個對象都會創建一個新函數showName(),即每個對象擁有不同的版本,但實際上他們共享的是同一個函數。

有些人把showName在工廠函數外定義,然後通過屬性指向該方法,可以避開這個問題:

代碼

可惜的是,這種方式讓showName()這個函數看起來不像對象的一個方法。

【構造函數方式】

這種方式是為了解決上面工廠函數的第一個問題,即沒有new運算符的問題。可是第二個問題它依然不能解決。我們來看看。

function Obj(name) {

this.name = name;

this.showName = function () {

alert(this.name);

}

}

var obj1 = new Obj(‘obj_one’);

var obj2 = new Obj(‘obj_two’);

它的好處是不用在構造函數內新建一個對象了,因為new運算符執行的時候會自動創建一個對象,並且只有通過this才能訪問這個對象。所以我們可以直接通過this來對這個對象進行賦值。而且不用再return,因為this指向默認為構造函數的返回值。

同時,用了new關鍵字來創建我們想要的對象是不是感覺更「正式」了。

可惜,它仍然不能解決會重複生成方法函數的問題,這個情況和工廠函數一樣。

【原型方式】

這種方式對比以上方式,有個很大的優勢,就是它解決了方法函數會被生成多次的問題。它利用了對象的prototype屬性。我們依賴原型可以重寫對象實例。

var Obj = function () {}

Obj.prototype.name = ‘me’;

Obj.prototype.showName = function () {

alert(this.name);

}

var obj1 = new Obj();

var obj2 = new Obj();

我們依賴原型對構造函數進行重寫,無論是屬性還是方法都是通過原型引用的方式給新建的對象,因此都只會被創建一次。可惜的是,這種方式存在兩個致命的問題:

1。沒辦法在構建對象的時候就寫入想要的屬性,因為原型在構造函數作用域外邊,沒辦法通過傳遞參數的方式在對象創建的時候就寫入屬性值。只能在對象創建完畢後對值進行重寫。

2。致命問題在於當屬性指向對象時,這個對象會被多個實例所共享。考慮下面的代碼:

var Obj = function () {}

Obj.prototype.name = ‘me’;

Obj.prototype.flag = new Array(‘A’, ‘B’);

Obj.prototype.showName = function () {

alert(this.name);

}

var obj1 = new Obj();

var obj2 = new Obj();

obj1.flag.push(‘C’);

alert(obj1.flag); // A,B,C

alert(obj2.flag); //A,B,C

是的,當flag屬性指向對象時,那麼實例obj1和obj2都共享它,哪怕我們僅僅改變了obj1的flag屬性,但是它的改變在實例obj2中任然可見。

面對這個問題,讓我們不得不想是否應該把【構造函數方式】和【原型方式】結合起來,讓他們互補。。。

【構造函數和原型混合方式】

我們讓屬性用構造函數方式創建,方法用原型方式創建即可:

var Obj = function (name) {

this.name = name;

this.flag = new Array(‘A’, ‘B’);

}

Obj.prototype = {

showName : function () {

alert(this.name);

}

}

var obj1 = new Obj();

var obj2 = new Obj();

obj1.flag.push(‘C’);

alert(obj1.flag); // A,B,C

alert(obj2.flag); //A,B

這種方式有效地結合了原型和構造函數的優勢,是目前用的最多,也是副作用最少的方式。

不過,有些追求完美的傢伙還不滿足,因為在視覺上還沒達到他們的要求,因為通過原型來創建方法的過程在視覺上還是會讓人覺得它不太像實例的方法(尤其對於傳統OOP語言的開發者來說。)

所以,我們可以讓原型活動起來,讓他也加入到構造函數裡面去,好讓這個構造函數在視覺上更為統一。而這一系列的過程只需用一個判斷即可完成。

var Obj = function (name) {

this.name = name;

this.flag = new Array(‘A’, ‘B’);

if (typeof Obj._init == ‘undefined’) {

Obj.prototype = {

showName : function () {

alert(this.name);

}

};

Obj._init = true;

}

}

如上,用_init作為一個標誌來判斷是否已經給原型創建了方法。如果是那麼就不再執行。這樣其實在本質上是沒有任何變化的,方法仍是通過原型創建,唯一的區別在於這個構造函數看起來「江山統一」了。

但是這種動態原型的方式是有問題的,《JavaScript高級程序設計》里並沒有深究。創建第一個對象的時候會因為prototype在對象實例化之前沒來的及建起來,是根本無法訪問的。所以第一個對象是無法訪問原型方法的。同時這種方式在子類繼承中也會有問題。

關於解決方案,我會在下一文中說明。

其實就使用方便來說的話,個人覺得是沒必要做這個判斷的。。。呵呵 ^_^

js class是方法還是對象

如果是ES6的話,CLASS是類。。。即不是方法也不是對象。。

ES6是面向對象的,所以自然就有類。。。原本的JS那套理論,是無法用來解釋面向對象的。

在面向對象的概念里。。。方法和屬性,都是從屬於類的。。。對象是類的實例。。類是創造對象用的模板。。如果把一輛汽車比作一個對象,那類就是汽車設計圖。。。

你用一個對象,可以「點」出什麼屬性和方法來,是由類決定的

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/279548.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-20 15:04
下一篇 2024-12-20 15:04

相關推薦

  • JS Proxy(array)用法介紹

    JS Proxy(array)可以說是ES6中非常重要的一個特性,它可以代理一個數組,監聽數據變化並進行攔截、處理。在實際開發中,使用Proxy(array)可以方便地實現數據的監…

    編程 2025-04-29
  • Idea新建文件夾沒有java class的解決方法

    如果你在Idea中新建了一個文件夾,卻沒有Java Class,應該如何解決呢?下面從多個方面來進行解答。 一、檢查Idea設置 首先,我們應該檢查Idea的設置是否正確。打開Id…

    編程 2025-04-29
  • Python Class括弧中的參數用法介紹

    本文將對Python中類的括弧中的參數進行詳細解析,以幫助初學者熟悉和掌握類的創建以及參數設置。 一、Class的基本定義 在Python中,通過使用關鍵字class來定義類。類包…

    編程 2025-04-29
  • Python語法大全解析

    本文旨在全面闡述Python語法,並提供相關代碼示例,幫助讀者更好地理解Python語言。 一、基礎語法 1、Python的注釋方式 # 這是單行注釋 “”” 這是多行注釋,可以注…

    編程 2025-04-29
  • 解析js base64並轉成unit

    本文將從多個方面詳細介紹js中如何解析base64編碼並轉成unit格式。 一、base64編碼解析 在JavaScript中解析base64編碼可以使用atob()函數,它會將b…

    編程 2025-04-29
  • Node.js使用Body-Parser處理HTTP POST請求時,特殊字元無法返回的解決方法

    本文將解決Node.js使用Body-Parser處理HTTP POST請求時,特殊字元無法返回的問題。同時,給出一些相關示例代碼,以幫助讀者更好的理解並處理這個問題。 一、問題解…

    編程 2025-04-29
  • Python中複數的語法

    本文將從多個方面對Python中複數的語法進行詳細的闡述。Python中的複數是指具有實部和虛部的數,其中實部和虛部都是浮點數。它們可以用「實數+虛數j」的形式表示。例如,3 + …

    編程 2025-04-29
  • parent.$.dialog是什麼技術的語法

    parent.$.dialog是一種基於jQuery插件的彈出式對話框技術,它提供了一個方便快捷的方式來創建各種類型和樣式的彈出式對話框。它是對於在網站開發中常見的彈窗、提示框等交…

    編程 2025-04-28
  • t3.js:一個全能的JavaScript動態文本替換工具

    t3.js是一個非常流行的JavaScript動態文本替換工具,它是一個輕量級庫,能夠很容易地實現文本內容的遞增、遞減、替換、切換以及其他各種操作。在本文中,我們將從多個方面探討t…

    編程 2025-04-28
  • JS圖片沿著SVG路徑移動實現方法

    本文將為大家詳細介紹如何使用JS實現圖片沿著SVG路徑移動的效果,包括路徑製作、路徑效果、以及實現代碼等內容。 一、路徑製作 路徑的製作,我們需要使用到SVG,SVG是可縮放矢量圖…

    編程 2025-04-27

發表回復

登錄後才能評論