CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

JavaScript中的强制类型转换[每日前端夜话0x4F]-源码交易平台丞旭猿

每日前端夜话0x4F

每日前端夜话,陪你聊前端。

每天晚上18:00准时推送。

正文共:2118 字

预计阅读时间: 10 分钟


翻译:疯狂的技术宅原文:https://www.valentinog.com/blog/coercion/

What is type coercion in JavaScript?

JavaScript 原语

JavaScript 建立在一系列基本单元之上。你应该对其中的一些已经很熟悉了,比如字符串和数字:

1vargreet ="Hello";2varyear =89;

字符串和数字是该语言所谓原语的一部分。完整清单是:

  • String

  • Number

  • Boolean

  • Null

  • Undefined

  • Object

  • Symbol (ES6中添加,此处不予介绍)

布尔值用来表示可能是真或假的值。null是故意不去赋值,它通常被分配给一个变量,用于表示绑定完毕,稍后将填充有意义的内容。

1varmaybe =null;

然后才是undefined,这意味着变量仍然没有被附加上:

1varname;2console.log(name)3undefined

null 和 undefined 看起来非常相似,但它们是两个截然不同的实体,很多开发人员仍然不确定应该使用哪个【https://github.com/sindresorhus/meta/issues/7】。

如果要判断 JavaScript 实例的类型,可以用typeof运算符。让我们用字符串尝试一下:

1typeof"alex"2>"string"

还有数字:

1typeof92>"number"

用于布尔值:

1typeoffalse2>"boolean"

undefined:

1typeofundefined2>"undefined"

还有 null:

1typeofnull2>"object"

结果令人惊讶! null 看起来像一个对象,但实际上它是 JavaScript 中的一个历史性错误,自语言诞生就躺在那里了。由于这些问题,JavaScript 一直声名狼借。但这仅仅是个开始。

陌生的事情

在 JavaScript 中,在两种类型之间进行转换时有一些奇怪的规则。让我给你一些背景信息。先用 Python 举一个例子。 在 Python 中执行以下指令:

1hello+89

会给你一个明确的错误:

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

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

1hello+89

事实上给出:

1"hello89"

如果我们尝试向字符串添加数组,看起来会更加奇怪:

1hello+ []

将会得到

11.hello

还有

11.hello+ [89]

会给你一个惊喜:

11."hello89"

看起来这种转换背后存在某种逻辑。它甚至适用于存在更多元素的 array :

11.hello+ [89,150.156,mike]

得到:

11."hello89,150.156,mike"

这两行 JavaScript 足以让 Java 程序员逃离。但是这种行为在 JavaScript 中 100% 是又意义的。因此这种隐式转换,也称为强制类型转换是非常值得探索的。

当一个数字变成一个字符串

一些编程语言有一个叫做类型转换的概念,这意味着:如果我想把一个数字或实例转换为另一种类型,那么我必须使显式转换。它也适用于 JavaScript。请看以下示例:

1vargreet ="Hello";2varyear =89;

如果我想明确的进行转换,可以在代码中表明意图:

1vargreet ="Hello";2varyear =89;34varyearString = year.toString()

要么这样做:

1vargreet ="Hello";2varyear =89;34varyearString =String(year)

然后我可以连接两个变量:

1greet + yearString;

但是在 JavaScript 中有一种被称为隐式转换的微妙机制,由JavaScript 引擎提供。该语言不会阻止我们对数字和字符串进行加法操作:

1hello+89

会得到:

1"hello89"

但是这种转换背后的逻辑是什么?你可能会惊讶地发现 JavaScript 中的加法运算符+会自动将两个操作数中的任何一个都转换为字符串,如果其中至少有一个是字符串的话

你会发现更令人惊讶的是,这条规则在ECMAScript规范中一脉相承。 第11.6.1节 【http://www.ecma-international.org/ecma-262/5.1/sec-11.6.1】定义了加法运算符的行为,我在这里为你做了总结:

如果 x 是 String 或 y 是String,则返回 ToString(x),然后返回ToString(y)

这个花招只适用于数字吗?并不是。数组和对象也会受到相同的转换

1hello+ [89,150.156,mike]

会得到:

1"hello89,150.156,mike"

那么下面的代码会得到怎样的结果:

1hello+ {name:"Jacopo"}

要找到答案,你可以通过将对象转换为字符串来进行快速测试:

1String({name:"Jacopo"})

将会得到:

1"[object Object]"

所以我有一种感觉:

11.hello+ {name:"Jacopo"}

会得到:

11."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 中有两个主要的比较运算符。

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

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

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

1"hello"=="hello"2>true34"hello"==="hello"5>true

看上去一切都还好。

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

11."1"===122.false

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

11."1"==122.true

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

如果适用相同的规则怎么办?没错! ECMAScript spec 【http://www.ecma-international.org/ecma-262/5.1/sec-11.9.3】再次罢工。结果抽象比较运算符在比较它们之前在类型之间进行自动转换。这是规范的摘要:

比较 x == y 执行如下:

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

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

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

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

那么强势比较怎么样?规范中的说 严格相等比较【http://www.ecma-international.org/ecma-262/5.1/sec-11.9.6在把值与三等===进行比较之前没有进行自动转换。在代码中使用严格相等比较可以避免愚蠢的 bug。

总结

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

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

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

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

求分享

如果你觉得这篇文章对你有帮助,请点击右下角的 🌸好看 并分享给小伙伴们↘️↘️↘️🙏🏼

下面夹杂一些私货:也许你和高薪之间只差这一张图

2019年京程一灯课程体系上新,这是我们第一次将全部课程列表对外开放。

愿你有个好前程,愿你月薪30K。我们是认真的 !

在公众号内回复体系查看高清大图

在公众号内回复体系查看高清大图

长按二维码,加大鹏老师微信好友

拉你加入技术交流群

唠一唠怎样才能拿高薪


往期精选文章
CSS粘性定位是怎样工作的
CSS Flexbox 可视化手册
2018年JavaScript状态调查

世界顶级公司的前端面试都问些什么

混合内容下的浏览器行为

12个令人惊奇的CSS实验项目

实战!半小时写一个脑力小游戏

JavaScript的工作原理:引擎、运行时和调用堆栈

使用虚拟dom和JavaScript构建完全响应式的UI框架
V8引擎内部机制及优化代码的5个技巧


小手一抖,资料全有。长按二维码关注前端先锋,阅读更多技术文章和业界动态。

声明:本文部分素材转载自互联网,如有侵权立即删除 。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容