文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript隐式类型转换例子总结

2022-11-13 14:32

关注

前言

熟练掌握类型转换,理解其中的规律。可以让你的代码更简洁更安全。

在编写代码的时候,我们通常会有意无意的写出一些,存在类型转换的代码。这些代码有时的返回值总让人迷惑,比如下列式子都是我们工作中常见的:

var a = 1;
var b = '2';
var c = a + b; // '12';

var d = 43;
d == '43';  // true
d === '43'; // false

上面都是比较常见的,让我们再看几个例子:

// 例子1
const obj = {
    toString() {
        return : 'xxx';
    }
}
const obj2 = {};

obj.toString();   // "xxx" 当然,我们还是可以使用Object.prototype.toString.call(obj)的,因为这是调用了Object对象,但是如果改写了Object的toString方法,那情况就不一样了。
obj2.toString();  // "[object Object]"

// 例子2
const a = [1,2,3];
const b = [4,5];
a + b;               // "1,2,34,5"

// 例子3
false == [];         // true
false == "";         // true
false == null;       // false
false == undefined;  // false
[] == ![];           // true

看到上面的结果,是否你也感觉头疼。现在让我们开始探索,看看这中间都发生了怎样的类型转换。

在讲强制类型转换是我们先思考一个问题,不同的数据类型值都会发生什么类型转换?在什么情况下会发生类型转换?具体是怎么转换的?

发生了类型转换通常都是操作值做了【抽象操作】(ES5规范第9节中定义了一些“仅供内部使用的操作”)。这里我们简单介绍一下ToStringToNumberToBoolean同时还有一个ToPrimitive

ToString

ToString是对非字符串进行强制类型转换。

var a = 1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
a.toString();  // "1.07e21";
var a = [1,2,3,4];
a.toString(); // "1,2,3,4"

var b = {
    a: 42,
    foo: 'foo'
}
b.toString(); // "[object Object]"

ToNumber

Number(true);      // 1
Number(false);     // 0
Number(null);      // 0
Number(undefined); // NaN
Number("");        // 0
Number("123");     // 123
Number("123aaa");  // NaN
var a = { valueOf() { return "42"} };
var b = { toString() { return "42"} };

var c = [1,2];
c.toString = function() { return this.join(""); }

Number(a);  // 42
Number(b);  // 42
Number(c);  // 12
Number([]); // 0
Number([1,2]); // NaN

ToBoolean

对于抽象操作ToBoolean,ES5规范9.2中列出一些假值,既对这些值进行布尔强制类型转换时,会转为false的值。除了这些值以外,所有值进行强制类型转换时,都会得到true

undefined
null
"" // 空字符串
+0, -0, NaN
false

ToPrimitive

抽象操作ToPrimitive,其实在ToStingToNumberToBoolean获取对象原始值的时候,就是通过ToPrimitive来获取的,获取完原始值之后,再进行toString(),Number(),Boolean()等类型转换。

总结,在对值进行类型转换时,如果是基本数据类型,则直接对使用该值进行类型转换;如果是引用类型,会先通过ToPrimitive获取原始值,然后使用获取的原始值进行类型转换。

而之前说的【先检查对象是否包含valueOf(),如果没有在检查toString()】这个过程就是 ToPrimitive

现在我们分析完类型转换的过程都具体做了什么操作了,现在我们看下,在那些操作下会发生类型转换。

运算符 +

如果操作数中存在字符串,则进行字符串拼接;如果操作数是对象,则会对对象进行 ToPrimitive抽象操作以获取原始值,通常这操作都会获取到字符串。最后进行 + 操作。

var a = [1,2];
var b = [3,4];
a + b;  // "1,23,4"

逻辑判断相关

上面的语句中所包含的判断表达式,都会将非布尔值通过抽象操作ToBoolean,将值转为boolean。

== 宽松对等规则

1. 字符串和数字之间的相等比较

var x = 42;
var y = '42';
x === y;  // false
x == y;   // true   这里转换为: 42 == ToNumber('42') => true

2. 其他类型和布尔类型的相等比较

var x = true;
var y = '42'
x === y; // false
x == y; // false
// false 这里转换为:toNumber(true) == toNumber('42') => 1 == 42  =>  false

3. null 和 undefined 之间的相等比较

注意: 在 == 中null和undefined相等(也与自身相等),除此之外其他值都不和他们相等 所以可以使用一特性,对值进行判断是否等于null或undefined

var x = null;
var y;
x === y; // false
x == y; //true

4. 对象和非对象之间的相等比较

var a = 42
var b = [42]

a == b; // true
// [42]调用ToPrimitive,返回"42",变成 "42" == 42,然后又变成 42 == 42,最后两者相等。

var a = "abc";
var b = Object(a); // new String( a )一样
a === b; // false
a == b; // true

这里有些值不一样

var a = null;
var b = Object(a); // 和Object()一样
a == b; // false

var c = undefined;
var d = Object(c); // 和Object()一样
c == d; // false

var e = NaN;
var f = Object(e); // 和new Number(e) 一样
e == f;  // NaN == NaN => false

因为js中,没有undefined 和 null 对应的封装对象。所以对他们进行Object封装跟调用Object()一样,返回一个常规对象。

而NaN是因为,NaN本身就不等于自己。

总结

总的来说:在宽松对比中,对比的值具有这样的转换优先级,对象 > 非对象(非对象中:字符串,布尔都会ToNumber转为数字,进行比较)。同时需要注意 NaN(唯一不等于自己的值),undefined和null这几个值的转换。

当然,宽松对等中不同值对比,才会进行类型转换。如果是相同类型的比较,不会进行类型转换。"0" == "" 返回false。因为这是字符串"0"""的对比,不会进行抽象操作ToNumber

理解了对象的类型转换都是ToPrimitive操作,那么我们需要注意,任何情况下都不要重写对象的 valueOf()toString() 方法。

到此这篇关于JavaScript隐式类型转换例子总结的文章就介绍到这了,更多相关JS隐式转换内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯