为了账号安全,请及时绑定邮箱和手机立即绑定

JavaScript基本类型的难点解析

undefined 类型

已经声明但未对其赋值的变量,是 undefined 类型。

例子:

var msg;
console.log(msg); //输出:undefined
console.log(typeof msg === "undefined"); //输出:true

*一般不需要显式地把一个变量设置为 undefined,因为没有赋值的变量默认就会取得 undefined。

还没有声明过的变量不属于 undefined 类型。

例子:

var a;
//var b;
console.log(a); //输出:undefined
console.log(b); //输出:ReferenceError: b is not defined

上例中,“b is not defined”容易让人误以为是“b is undefined”,实际上,“undefined”和“is not defined”是两码事,“is not defined”是没有定义的意思,此时如果浏览器报错成“b is not found”或者“b is not declared”会更准确。但是,如果使用 typeof 操作符打印这种没有声明的变量时,照样返回 “undefined”,虽然 b 并不属于 undefined 类型。

例子:

var a;
//var b;
console.log(typeof a); //输出:undefined
console.log(typeof b); //输出:undefined

*typeof b 没有报错的原因是 typeof 的安全防范机制在起作用。

null 类型

理论上,null 值的数据类型应该是"null"。但 typeof 对它的处理有问题。

例子:

console.log(typeof null);
//输出:object

正确的返回结果应该是 “null”,但这个 bug 由来已久,修复的机率已经很小。

undefined 类型 和 null 类型对比

相同点

1、undefined 类型只有一个值,即 undefined。null 类型也只有一个值,即 null。它们的名称既是类型也是值。
2、undefined 值是派生自 null 值,因此 null 和 undefined 之间的相等操作符(==)返回 true。

不同点

1、undefined 指声明而未赋值,null 指曾赋过值,但是目前没有值。

boolean 类型

boolean 类型只有两个字面值:true和false。但 JavaScript 中所有类型的值都有与这两个boolean 值等价的值。

可以自动转换成true的值:

string类型:任何非空字符串
boolean类型:true
number类型:任何非零数字值
object类型:任何对象

可以自动转换成false的值:

string类型:空字符串
boolean类型:false
number类型:零和NaN
object类型:null
undefined类型:undefined

测试代码:

var array=["hello",true,2,{}];
var n=0;
for(var i=0,len=array.length;i<len;i++){
    if(array[i]){
        n++
    }
}
console.log(n+"个为true")
//输出:4个为true
var array=["",false,0,NaN,null,undefined];
var n=0;
for(var i=0,len=array.length;i<len;i++){
    if(!array[i]){
        n++
    }
}
console.log(n+"个为false")
//输出:6个为false

number 类型

NaN

NaN,即无效数字(Not a Number)是一个特殊的数值,如果执行数学运算没有成功,这是失败后返回的结果”。NaN本身有两个非同寻常的特点。首先,任何涉及NaN的操作(例如NaN/10)都会返回NaN。其次,NaN与任何值都不相等,包括NaN本身。

例子:

var a = "hello" / 2;
console.log(a); //输出:NaN
console.log(a == NaN); //输出:false
console.log(a === NaN); //输出:false

由于我们无法直接对一个计算值是否为 NaN 进行判断(结果永远为 false),因此引入了一个全局函数 isNaN()。 这个函数接受一个参数,该参数可以是任何类型,当参数值为 NaN 的时候才会返回 true。

例子:

console.log(isNaN(NaN)); //输出:true
console.log(isNaN('hello' * 2)); //输出:true
console.log(isNaN(undefined)); //输出:true       
console.log(isNaN("love")); //输出:true
console.log(isNaN({})); //输出:true

console.log(isNaN(10)); //输出:false
//字符串"10"被强制转换成数字 10
console.log(isNaN("10")); //输出:false
console.log(isNaN("10.0")); //输出:false
//true被强制转换成数字 1
console.log(isNaN(true)); //输出:false
//null被强制转换成数字 0
console.log(isNaN(null)); //输出:false
//""被强制转换成数字 0
console.log(isNaN("")); //输出:false
//" "被强制转换成数字 0
console.log(isNaN(" ")); //输出:false

通过上面的例子可以发现,isNaN() 有两个严重的缺陷:字符串 “love” 虽然不是一个数字,但是它也不是 NaN,还有 undefined 和 对象 {} 也同样如此;另外,isNaN() 会强制将参数转换成数字,只有那些无法被转换成数字的参数才会返回 true。
基于以上两点缺陷,ES6 增加了方法 Number.isNaN(),这个方法不会强制将参数转换成数字,只有在参数是真正的数字类型,且值为 NaN 的时候才会返回 true。

例子:

console.log(Number.isNaN(NaN)); //输出:true
console.log(Number.isNaN('hello' * 2)); //输出:true

//非 NaN,所以返回 false
console.log(Number.isNaN(10)); //输出:false
//非数字类型,所以返回 false
console.log(Number.isNaN(undefined)); //输出:false
console.log(Number.isNaN("love")); //输出:false
console.log(Number.isNaN({})); //输出:false
console.log(Number.isNaN("10")); //输出:false
console.log(Number.isNaN("10.0")); //输出:false
console.log(Number.isNaN(true)); //输出:false
console.log(Number.isNaN(null)); //输出:false
console.log(Number.isNaN("")); //输出:false
console.log(Number.isNaN(" ")); //输出:false

对于不支持 Number.isNaN() 方法的浏览器,可以写以下函数:

代码如下:

if (!Number.isNaN) {
    Number.isNaN = function(n) {
        return (
            typeof n === "number" &&
            window.isNaN(n)
        );
    };
}

负零值

在 JavaScript 中,+0(或 0 ) 和 -0是两个完全不同是数字。

例子:

console.log(0 / -1); //输出:-0
console.log(0 * -1); //输出:-0
console.log(0 / 1); //输出:0
console.log(0 * 1); //输出:0

*加法和减法运算不会得到负零。

但使用全等运算符(===)对 +0 和 -0 进行比较,两者却相等。

例子:

console.log(0 === -0); //输出:true

综上两种特殊的数字类型,NaN 和 -0 ,在相等比较时表现的特殊性,ES6 中引入了一个新方法 Object.is(),用来判断两个值是否绝对相等。这个方法主要用来处理NaN 与 NaN 不相等,和 +0 与 -0 相等这两种特殊的比较。

例子:

console.log(Object.is(0, -0)); //输出:false
console.log(Object.is(NaN, NaN)); //输出:true

string 类型

字符串由单引号( ’ )、双引号( " )或反引号( ` )表示。字符串和数组很相似,都有 length 属性以及slice()、 indexOf() 、concat()和 includes() 方法。但字符串是不可变的,而数组是可变的。字符串不可变是指,任何操作都不会改变字符串的原始值,而只会创建并返回一个新的字符串。而对于数组的操作可以在其原始值上进行。

例子:

var a = 'love';
var b = a.replace('love', 'hate');

//变量 a 的原始值不变
console.log(a); //输出:love
console.log(b); //输出:hate

var arr = a.split();
arr.splice(0, 1, 'hate');

//数组 arr 的原始值被改变
console.log(arr); //输出:["hate"]

字符串可以通过“借用”数组的方法来处理字符串:

例子:

var a = 'love';
var b = Array.prototype.join.call(a, '-');
console.log(b); //输出:l-o-v-e

*数组有一些可以直接变更数组成员的方法,字符串无法“借用”。

例子:

var a = 'love';
Array.prototype.pop.call(a); //输出:报错
Array.prototype.reverse.call(a); //输出:报错
Array.prototype.splice.call(a, 0, 1, 'm'); //输出:报错

文中的代码部分,带有“例子”和“测试代码”字样的,只是用来学习或测试某一功能用的代码,不可以直接用于项目的开发中。带有“代码如下”字样的,都是经过本人测试,简单修改即可用于项目开发中的代码,如有错误,欢迎指出。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消