首頁  >  文章  >  web前端  >  JavaScript中的強制型別轉換的方法介紹

JavaScript中的強制型別轉換的方法介紹

不言
不言轉載
2019-04-12 10:55:222263瀏覽

這篇文章帶給大家的內容是關於JavaScript中的強制型別轉換的方法介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

JavaScript 原語

JavaScript 建立在一系列基本單元之上。你應該對其中的一些已經很熟悉了,例如字串和數字:

var greet = "Hello";
var year = 89;

字串和數字是該語言所謂「原語」的一部分。完整清單是:

  • String
  • Number
  • Boolean
  • Null
  • Undefined
  • Object
  • Symbol (ES6中添加,此處不予介紹)

布林值用來表示可能是真或假的值。 null 是故意不去賦值,它通常被分配給一個變量,用於表示綁定完畢,稍後將填充有意義的內容。

var maybe = null;

然後才是undefined,這表示變數仍然沒有被附加上:

var name;
console.log(name)
undefined

null 和undefined 看起來非常相似,但它們是兩個截然不同的實體,很多開發人員仍然不確定應該使用哪一個。

如果要判斷 JavaScript 實例的類型,可以用 typeof 運算子。讓我們用字串嘗試一下:

typeof "alex"
> "string"

還有數字:

typeof 9
> "number"

用於布林值:

typeof false
> "boolean"

undefined:

typeof undefined
> "undefined"

還有null :

typeof null
> "object"

結果令人驚訝! null 看起來像一個對象,但實際上它是 JavaScript 中的一個歷史性錯誤,自語言誕生就躺在那裡了。 由於這些問題,JavaScript 一直聲名狼借。但這只是個開始。

陌生的事情

在 JavaScript 中,在兩種類型之間進行轉換時有一些奇怪的規則。讓我給你一些背景資訊。先用 Python 舉個例子。在Python 中執行以下指令:

'hello' + 89

會給你一個明確的錯誤:

TypeError: can only concatenate str (**not** "int") to str

而在JavaScript 中,只有天空才是你的極限:

'hello' + 89

事實上給出:

"hello89"

如果我們嘗試向字串添加數組,看起來會更加奇怪:

'hello' + []

將會得到

1. 'hello'

還有

1. 'hello' + [89]

會給你一個驚喜:

1. "hello89"

看起來這種轉換背後存在著某種邏輯。它甚至適用於存在更多元素的 array :

1. 'hello' + [89, 150.156, 'mike']

得到:

1. "hello89,150.156,mike"

這兩行 JavaScript 足以讓 Java 程式設計師逃離。但是這種行為在 JavaScript 中 100% 是又意義的。因此這種隱式轉換,也稱為強制型別轉換是非常值得探索的。

當一個數字變成一個字串

一些程式語言有一個叫做型別轉換的概念,這表示:如果我想把一個數字或實例轉換為另一種類型,那麼我必須使明確轉換。它也適用於 JavaScript。請看以下範例:

var greet = "Hello";
var year = 89;

如果我想明確的進行轉換,可以在程式碼中表明意圖:

var greet = "Hello";
var year = 89;

var yearString = year.toString()

要么這樣做:

var greet = "Hello";
var year = 89;

var yearString = String(year)

然後我可以連接兩變數:

greet + yearString;

但在JavaScript 中有一個稱為隱含轉換的微妙機制,由JavaScript 引擎提供。語言不會阻止我們對數字和字串進行加法操作:

'hello' + 89

會得到:

"hello89"

但是這種轉換背後的邏輯是什麼?你可能會驚訝地發現JavaScript 中的加法運算子 會自動將兩個運算元中的任何一個轉換為字串,如果其中至少有一個是字串的話

你會發現更令人驚訝的是,這條規則在ECMAScript規範中一脈相承。第11.6.1節定義了加法運算子的行為,我在這裡為你做了總結:

#如果x 是String 或y 是String,則傳回ToString(x),然後回傳ToString(y)

這個花招只適用於數字嗎?並不是。 陣列和物件也會受到相同的轉換

'hello' + [89, 150.156, 'mike']

會得到:

"hello89,150.156,mike"

那麼下面的程式碼會得到怎樣的結果:

'hello' + { name: "Jacopo" }

#要找到答案,你可以透過將物件轉換為字串來進行快速測試:

String({ name: "Jacopo" })

將會得到:

"[object Object]"

所以我有一種感覺:

1. 'hello' + { name: "Jacopo" }

會得到:

1. "hello[object Object]"

打住!這又是什麼?

JavaScript 中 [object Object] 的意思是什麼?

「[object Object]」 是最常見的 JavaScript 「怪癖」之一。

幾乎每個 JavaScript 實例都有一個名為 toString() 的方法,有些方法是由 Object.prototype.toString 提供的。
某些類型(如陣列)實作了 toString() 的自訂版本,以便在呼叫方法時將值轉換為字串。例如 Array.prototype.toString 會覆寫 Object.toString()(也稱為 method shadowing)。

但是当你在普通的 JavaScript 对象上调用 toString() 时,引擎会给出“[object Object]”,因为 Object.toString()默认行为是由实体类型(在这种情况下为Object)返回字符串 object

现在让我们把注意力集中在 JavaScript 比较运算符上,它们与算术运算符一样奇怪。

等于还是不等于?

JavaScript 中有两个主要的比较运算符。

第一个我们称之为“弱比较”。这是抽象比较运算符(双等号):==

另一个是“强比较”,可以通过三等号进行识别:=== 也称为严格比较运算符。它们两者的行为方式完全不同。

来看一些例子。首先,如果我们将两个字符串与两个运算符进行比较,我们得到相同的结果

"hello" == "hello"
> true

"hello" === "hello"
> true

看上去一切都还好。

现在尝试比较两种不同的类型,数字和字符串。首先是“强比较”:

1. "1" === 1
2. false

这说得通!字符串“1”与数字1是不同的。但是“弱比较”会发生什么?

1. "1" == 1
2. true

居然是true!它没有任何意义,除非这种行为与我们之前看到的隐式转换有关。

如果适用相同的规则怎么办?没错! ECMAScript spec 再次罢工。结果抽象比较运算符在比较它们之前在类型之间进行自动转换。这是规范的摘要:

比较 x == y 执行如下:

如果 x 是 String 且 y 是Number,则返回比较结果 ToNumber(x)== y

规范说:如果第一个操作数是一个字符串,第二个操作数是一个数字,那么将第一个操作数转换为数字。有趣。

JavaScript 规范充满了这个疯狂的规则,我强烈鼓励大家对它深入挖掘。

在此期间除非你有充分的理由否则在 JavaScript 代码中避免使用抽象比较运算符。你以后会感谢自己的。

那么“强势比较”怎么样?规范中的说 严格相等比较在把值与三等 === 进行比较之前没有进行自动转换。在代码中使用严格相等比较可以避免愚蠢的 bug。

总结

JavaScript 中有七个构建块,即 StringNumberBooleanNullUndefinedObjectSymbol。这些类型被称为基元

JavaScript 开发人员可以使用算术和比较运算符来操作这些类型。但是我们要特别注意加法运算符 +抽象比较运算符 ==,它本质上倾向于在类型之间进行转换。

JavaScript 中的隐式转换称为强制类型转换,并在 ECMAScript 规范中定义。无论什么时候你的代码都要使用严格的比较运算符 === 而不是 ==

作为最佳实践,当你打算在两种类型之间进行转换时,请务必明确操作。JavaScript 有一堆内置对象,它们反映了原始类型:StringNumberBoolean。这些内置类型可用于在不同类型之间进行显式转换。

以上是JavaScript中的強制型別轉換的方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除