JavaScript隱式類型轉換,javascript隱轉換

來源:互聯網
上載者:User

JavaScript隱式類型轉換,javascript隱轉換

JavaScript的資料類型是非常弱的(不然不會叫它做弱類型語言了)!在使用算術運算子時,運算子兩邊的資料類型可以是任意的,比如,一個字串可以和數字相加。之所以不同的資料類型之間可以做運算,是因為JavaScript引擎在運算之前會悄悄的把他們進行了隱式類型轉換的,如下是數實值型別和布爾類型的相加:

複製代碼 代碼如下:
3 + true; // 4

結果是一個數值型!如果是在C或者Java環境的話,上面的運算肯定會因為運算子兩邊的資料類型不一致而導致報錯的!但是,在JavaScript中,只有少數情況下,錯誤類型才會導致出錯,比如調用非函數,或者讀取null或者undefined的屬性時,如下:

複製代碼 代碼如下:
"hello"(1); // error: not a function
null.x; // error: cannot read property 'x' of null

多數情況下,JavaScript都不會出錯的,而是自動的進行相應的類型轉換。比如-, *, /,和%等算術運算子都會把運算元轉換成數位,但是“+”號就有點不一樣了,有些情況下,它是算術加號,有些情況下,是字串串連符號,具體的要看它的運算元,如下:

複製代碼 代碼如下:
2 + 3; // 5
"hello" + " world"; // "hello world"

但是,如果字串和數字相加,會是怎樣的結果呢?JavaScript會自動把數字轉換成字元的,不管數字在前還是字串在前,如下:

複製代碼 代碼如下:
"2" + 3; // "23"
2 + "3"; // "23"

字串和數字相加結果是字串,字串和數字相加結果是字串,字串和數字相加結果是字串,重要的事情說三遍!!!!!!

此外,需要注意的是,“+”的運算方向是從左至右的,如下:

複製代碼 代碼如下:
1 + 2 + "3"; // "33"

這與下面是等價的:

複製代碼 代碼如下:
(1 + 2) + "3"; // "33"

相比之下,下面的結果是不一樣的:

複製代碼 代碼如下:
1 + "2" + 3; // "123"

但是,隱式類型轉換,有時候,會隱藏一些錯誤的,比如,null會轉換成0,undefined會轉換成NaN。需要注意的是,NaN和NaN是不相等的(這是由於浮點數的精度決定的),如下:

複製代碼 代碼如下:
var x = NaN;
x === NaN; // false

雖然,JavaScript提供了isNaN來檢測某個值是否為NaN,但是,這也不太精確的,因為,在調用isNaN函數之前,本身就存在了一個隱式轉換的過程,它會把那些原本不是NaN的值轉換成NaN的,如下:

複製代碼 代碼如下:
isNaN("foo"); // true
isNaN(undefined); // true
isNaN({}); // true
isNaN({ valueOf: "foo" }); // true

上面代碼,我們使用isNaN來測試後,發現字串,undefined,甚至對象,結果都返回真!!!但是,我們總不能說他們也是NaN吧?總而言之,得出的結論是:isNaN檢測NaN並不可靠!!!

幸運的是,有一種可靠的並且準確的方法可以檢測NaN。我們都知道,只有NaN是自己不等自己的,那麼,我們就以使用不等號(!==)來判斷一個數是否等於自身,從而,可以檢測到NaN了,如下:

var a = NaN;a !== a; // truevar b = "foo";b !== b; // falsevar c = undefined;c !== c; // falsevar d = {};d !== d; // falsevar e = { valueOf: "foo" };e !== e; // false

我們也可以把這種模式定義成一個函數,如下:

function isReallyNaN(x) {return x !== x;}

OK,NaN的檢測方法就是這麼簡單,我們下面繼續討論對象的隱式轉換!

對象是可以轉換成原始值的,最常見的方法就是把它轉換成字串,如下:

"the Math object: " + Math; // "the Math object: [object Math]""the JSON object: " + JSON; // "the JSON object: [object JSON]"

對象轉換成字串是調用了他的toSting函數的,你可以手動的調用它來檢測一下:

Math.toString(); // "[object Math]"JSON.toString(); // "[object JSON]"

類似的,對象也是可以轉換成數位,他是通過valueOf函數的,當然,你也是可以自訂這個valueOf函數的,如下:

"J" + { toString: function() { return "S"; } }; // "JS"2 * { valueOf: function() { return 3; } }; // 6

如果,一個對象同時存在valueOf方法和toString方法,那麼,valueOf方法總是會被優先調用的,如下:

var obj = {toString: function() {return "[object MyObject]";},valueOf: function() {return 17;}};"object: " + obj; // "object: 17"

但是,多數情況下,這都不是我們想要的,一般的,儘可能使valueOf和toString表示的值相同(儘管類型可以不同)。

最後一種強制類型轉換,我們常常稱之為“真值運算”,比如,if, ||, &&,他們的運算元不一定是布爾型的額。JavaScript會通過簡單的轉換規則,將一些非布爾類型的值轉換成布爾型的。大多數的值都會轉換成true,只有少數的是false,他們分別是:false, 0, -0, ”", NaN, null, undefined,因為存在數字和字串以及對象的值為false,所以,直接用真值轉換來判斷一個函數的參數是否傳進來了,這是不不太安全的。比如,有一個可以具有預設值得選擇性參數的函數,如下:

function point(x, y) {if (!x) {x = 320;}if (!y) {y = 240;}return { x: x, y: y };}

這個函數會忽略任何的真值為假的參數的,包括0,-0;

複製代碼 代碼如下:
point(0, 0); // { x: 320, y: 240 }

檢測undefined的更加準確的方法是用typeof操作:

function point(x, y) {if (typeof x === "undefined") {x = 320;}if (typeof y === "undefined") {y = 240;}return { x: x, y: y };}

這種寫法,可以區分開0和undefined的:

point(); // { x: 320, y: 240 }point(0, 0); // { x: 0, y: 0 }

另外一種方法是利用參數跟undefined作比較,如下:

if (x === undefined) { ... }

總結:

1. 類型錯誤有可能會被類型轉換所隱藏。

2. “+”既可以表示字串串連,又可以表示算術加,這取決於它的運算元,如果有一個為字串的,那麼,就是字串串連了。

3. 對象通過valueOf方法,把自己轉換成數字,通過toString方法,把自己轉換成字串。

4.具有valueOf方法的對象,應該定義一個相應的toString方法,用來返回相等的數位字串形式。

5.檢測一些未定義的變數時,應該使用typeOf或者與undefined作比較,而不應該直接用真值運算。

關於JavaScript隱式類型轉換就給大家介紹到這裡,希望對大家有所協助!

您可能感興趣的文章:
  • 淺析JavaScript中的隱式類型轉換
  • 簡單介紹JavaScript資料類型之隱式類型轉換

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.