JavaScript中的强制类型转换

JavaScript primitives(原语)

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" === 12. false

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

1. "1" == 12. true

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

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

比较 x == y 执行如下:

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

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

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

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

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

总结

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

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

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

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

原文地址:https://www.valentinog.com/blog/coercion/

Image placeholder
前端答疑
未设置
  57人点赞

没有讨论,发表一下自己的看法吧

推荐文章
Python教程-强制数据类型转换

数据类型转换分为两种,一种是自动数据类型转换(隐式)和强制数据类型转换(显式)原则上不同的数据之间无法进行运算,自动数据类型转换是程序自发的行为,比如在运算时(或判断时)。在需要的情况下进行的操作

JavaScript类型转换

其他类型转化成Number类型: 1.通过Number()将其他类型转换成数值类型,但是转换的变量为字符串时,若不是数字字符串,则返回NaN 2.通过parseInt()将其他类型转换成数值类型,但是

JavaScript类型转换

浮点数转化 通过parseFloat()将其他类型转换成浮点数,与parseInt()相同.

JavaScript中的Infinity(无穷)

Infinity(无穷)在JS中是一个特殊的数字,它的特性是:它比任何有限的数字都大,如果不知道Infinity,我们在一些运算操作遇到时,就会觉得很有意思。现在我们来看看JS中的Infinity属性

Go语言高级编程_2.3 类型转换

2.3类型转换 最初CGO是为了达到方便从Go语言函数调用C语言函数(用C语言实现Go语言声明的函数)以复用C语言资源这一目的而出现的(因为C语言还会涉及回调函数,自然也会涉及到从C语言函数调用Go语

数据类型转换

只有容器类数据才能转换为容器类数据。非容器类数据无法朝着容器类数据转换,因为无法进行迭代。 dict转为列表时仅保留键会舍弃值。转为元组享有和转为列表相同的特征。 转为set时会进行去重的操作,并且为

数据类型转换及常量笔记

var_dump() var_dump();该功能可以直接将数据的值和类型显示出来 优点:既可以查看变量类型也可以查看值 缺点:类型和值的结果无法被接收,后续代码无法使用 gettype() 获

JavaScript中对“this”的简单理解

1.this的奥秘很多时候,JS中的this对于咱们的初学者很容易产生困惑不解。this的功能很强大,但需要一定付出才能慢慢理解它。对Java、PHP或其他标准语言来看,this表示类方法中当前对象的

如何在JavaScript中操作数组?

JavaScript中的数组是什么?在开始之前,你需要先了解数组的真正含义。在JavaScript中,数组是一个用于存储不同数据类型的变量。它将不同的元素存储在一个盒子中,供以后使用。声明一个数组:l

可视化的JavaScript:JavaScript引擎运行原理

JavaScript很酷,但是JavaScript引擎是如何才能理解我们编写的代码呢?作为JavaScript开发人员,我们通常不需要自己处理编译器。然而,了解JavaScript引擎的基础知识并了解

零基础学习Swift中的数据科学

概述Swift正迅速成为数据科学中最强大、最有效的语言之一Swift与Python非常相似,所以你会发现2种语言的转换非常平滑我们将介绍Swift的基础知识,并学习如何使用该语言构建你的第一个数据科学

react中的webpack是什么?

Webpack是一个开源的前端打包工具。Webpack提供了前端开发缺乏的模块化开发方式,将各种静态资源视为模块,并从它生成优化过的代码。Webpack可以从终端、或是更改webpack.config

JavaScript数据类型笔记

toString()方法可以转换除了null和undefined,使用String()可以将null与undefined转换成字符串.

浏览器中的JavaScript:什么是文档对象模型?什么是DOM操作?

JavaScript并没有那么糟糕。作为运行在浏览器中的脚本语言,它对于网页操作非常有用。在本文中,我们将看到可以用哪些手段来修改HTML文档和交互。什么是文档对象模型?文档对象模型是在浏览器中一切的

怎么在react中安装修饰器

怎么在react中安装修饰器在create-react-app下使用es7的@修饰器会报错''Supportfortheexperimentalsyntax'decorators-legacy'isn

怎么在react中使用weui

怎么在react中使用weui1、react没有安装的情况下:安装react和weuinpminstall--savereactreact-dom npminstall--saveweui@1.1.0

在react中怎么引用js

在react中怎么引用js推荐两种引入的方法,当然也可以自己编写一个JS类(ES6语法)实现动态插入JS到页面,然后在React项目引入。第一种:使用插件react-load-script如果没有安装

react中如何使用组件

react中如何使用组件前文我们介绍过了《如何写react组件》(感兴趣的同学可以过去学习),下面我们来说一下如何使用react组件。1、无状态组件的使用方法组件:constApp=(props)=>

如何将echarts集成到react中

如何将echarts集成到react中在使用echarts之前需要先安装echarts,可以直接使用node命令来安装npminstallecharts--save包依赖安装完毕后,这个时候我们的EC

JS 中一定要了解的数据类型和数据转换

数据类型 前言 Js中的类型只有6种,其中基本数据类型有5种分别为string,number,boolen,null,undefined,引用类型有一种,就是object,object是一个大的综合

JS 中一定要了解的数据类型和数据转换

Js数据类型 前言 Js中的类型只有6种,其中基本数据类型有5种分别为string,number,boolen,null,undefined,引用类型有一种,就是object,object是一个大的

美埃默里大学华人实验室突遭关闭,两华人教授及部分中国雇员被强制遣返

大数据文摘出品作者:魏子敏、宋欣仪据美《科学》杂志报道,佐治亚州亚特兰大的埃默里大学(EmoryUniversity)突然关闭了知名华人生物学家李晓江和李世华教授夫妇的实验室。22日,埃默里大学解雇了

深度解析微信域名经常被封的防封方案与已被封域名强制浏览器打开的防封短链接实现!

很多做H5(QP、BC、CP)的朋友都会经常遇到域名被微信秒封的情况。导致推广出去的二维码和链接用户打不开,这样会错失很多流量。这个问题一直让很多朋友头疼,因为微信推广的效率确实很理想,用户量的裂变也

Go 语言数据类型:字符类型

字符类型 字符基本输入与输出 所谓字符类型是用单引号括起来的单个字符,关于字符的定义使用如下: funcmain(){ //声明变量 varchbyte//声明字符类型 chbyte='a'//单引号

喊话 JavaScript 开发者:玩 DOM 也要专业范儿

别再害怕DOM了,让我们充分挖掘DOM的潜力,你会真的爱上它。 2008年,当我刚成为一名专业Web开发人员参加工作时,我了解一些HTML、CSS和PHP的知识。那时我也在学习JavaScript