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'); //输出:报错
文中的代码部分,带有“例子”和“测试代码”字样的,只是用来学习或测试某一功能用的代码,不可以直接用于项目的开发中。带有“代码如下”字样的,都是经过本人测试,简单修改即可用于项目开发中的代码,如有错误,欢迎指出。
共同学习,写下你的评论
评论加载中...
作者其他优质文章