数据类型的分类
基本数据类型
,也叫做原始类型、简单数据类型,表示不可再分的类型
- Number
- String
- Boolean
- Null
- Undefined
- Symbol(ES6)
引用数据类型
:也叫做复杂数据类型
- object:字面量对象、数组、正则表达式、日期对象、Math、实例对象、…
- function
检测有效数字使用 isNaN
NaN 不是一个有效数字,但属于 number 数字类型,NaN 和谁都不相等;
其他数据类型转换成数字类型,不能转换就是 NaN;
let a = Number("111");
let b = Number("qwe");
console.log(isNaN(a)); // false
console.log(isNaN(b)); // true
console.log(isNaN("A")); // true
数据类型的转换
JavaScript 是一种动态类型语言,变量没有类型限制,可以随时赋予任意值;
类型转化
-
由于自动转换具有不确定性,建议在预期为布尔值、数值、字符串的地方,全部使用 Boolean()、Number() 和 String() 函数进行显式转换;遇到以下三种情况时,JavaScript 会自动转换数据类型,即转换是自动完成的,用户不可见:
- 第一种情况,不同类型的数据互相运算;
- 第二种情况,对非布尔值类型的数据求布尔值;
- 转化为 false 的值:false、undefined、null、‘’、0、NaN;
- 转化为 true 的值:除了转化为 false 的值;
- 第三种情况,对非数值类型的值使用一元运算符(即
+
和-
);
-
对象的转化(求对象的原始值)会先执行 valueOf() ,若 valueOf() 返回的值还是对象则会执行 toString();
// eg1: let obj1 = { valueOf() { return 100; }, toString() { return 200; }, }; console.log(true + obj1); // 101 // eg2: let obj2 = { valueOf() { return {}; }, toString() { return 200; }, }; console.log(true + obj2); // 201
面试题
第 1 题:object 的 key 值
只能是基本类型值,最后会转成字符串;
会把 引用类型值 转换成 字符串 [object Object];
var a = {}, b = '123', c = 123;
a[b] = 'b';
a[c] = 'c';
// a['123'] 等价 a[123],则 a[b]、a[c] 等于 c
console.log(a[b]); // c
let a = { x: 100 };
let b = { y: 200 };
let obj = {};
obj[a] = 'aaa'; //=> { '[object Object]': 'aaa' }
obj[b] = 'bbb'; //=> { '[object Object]': 'bbb' }
console.log(obj); //=> { '[object Object]': 'bbb' }
第 2 题:object 的 key 值为 Symbol
var a = {}, b = Symbol('123'), c = Symbol('123')
a[b] = 'b';
a[c] = 'c';
// Symbol 是 ES6 中新增的数据类型,创建的值为唯一值,b 不等于 c
console.log(a[b]); // b
第 3 题:值和引用
// 第一题
var foo = {
n: 0,
k: {
n: 0,
},
};
var bar = foo.k;
bar.n++;
bar = {
n: 10,
};
bar = foo;
bar.n++;
bar = foo.n;
bar++;
console.log(foo.n, foo.k.n);
// 第二题
var foo = {
n: 1,
};
var arr = [foo];
function method1(arr) {
var bar = arr[0];
arr.push(bar);
bar.n++;
arr = [bar];
arr.push(bar);
arr[1].n++;
}
function method2(foo) {
foo.n++;
}
function method3(n) {
n++;
}
method1(arr);
method2(foo);
method3(foo.n);
console.log(foo.n, arr.length);
// 第三题
var foo = { bar: 1 };
var arr1 = [1, 2, foo];
var arr2 = arr1.slice(1);
arr2[0]++;
arr2[1].bar++;
foo.bar++;
arr1[2].bar++;
console.log(arr1[1] === arr2[0]);
console.log(arr1[2] === arr2[1]);
console.log(foo.bar);
第 6 题:0.1 + 0.2 是否等于 0.3
console.log(parseInt('1010', 2)); // 10
console.log((10).toString(2)); // 1010
/*
10进制 => 2进制 技巧
- 整数位:当前位的值 *2^(n-1)
- 小数位:把当前的不停乘 2 取整
0.1 转成 2机制
0.1 * 2 = 0.2 无整数 0.0
0.2 * 2 = 0.4 无整数 0.00
0.4 * 2 = 0.8 无整数 0.000
0.8 * 2 = 1.6 无整数 0.0001
0.6 * 2 = 1.2 无整数 0.00011
0.2 * 2 = 0.4 无整数 0.000110
...... 无限循环小数
*/
console.log((0.1).toString(2));
// 0.0001100110011001100110011001100110011001100110011001101......
console.log((0.2).toString(2));
// 0.001100110011001100110011001100110011001100110011001101......
console.log((0.3).toString(2));
// 0.0100110011001100110011001100110011001100110011001101 转成十进制为 0.30000000000000004
a 等于什么值会让「a == 1 && a == 2 && a == 3 」条件成立;
// 方式一:数值和对象比较,先执行 valueOf,如果还是对象则再执行 toString
var a = {
i: 1,
toString() {
return a.i++;
}
};
if (a == 1 && a == 2 && a == 3) {
console.log('OK');
}
// 方式二:数值和对象比较,先执行 valueOf,如果还是对象则再执行 toString
var a = {
i: 1,
valueOf() {
return a.i++;
}
};
if (a == 1 && a == 2 && a == 3) {
console.log('OK');
}
// 方式三:
var a = [1, 2, 3];
a.toString = a.shift;
if (a == 1 && a == 2 && a == 3) {
console.log('OK');
}
// 方式四:
var a = [1, 2, 3];
a.valueOf = a.shift;
if (a == 1 && a == 2 && a == 3) {
console.log('OK');
}
// 方式五:
var i = 0;
Object.defineProperty(window, 'a', {
get() {
// 获取 window.a 的时候触发
return ++i;
},
set() {
// 给 window.a 设置属性值的时候触发
}
});
if (a == 1 && a == 2 && a == 3) {
console.log('OK');
}
[] == ![] 的结果是 true 吗
console.log([] == ![]); // true
// 1. 单目运算符优先级更高,![] 是一个表达式,则 ![] => fasle
// 2. [] 要转成原始值,先执行 valueOf,若返回值为对象继续执行 toString
// [].valueOf() = [],[] == false
// [].toString() = '','' == false
// 3. '' == false
// Number('') => 0
// false => 0
// 4. 0 == 0 => true
正则表达式👉 案例
上一篇