数据类型检测
- 基本数据类型和函数类型检测使用typeof
typeof variable === 'string'
typeof variable === 'number'
typeof variable === 'boolean'
typeof variable === 'undefined'
typeof variable === 'function'
- 判断是否是null或undefined
variable == null
- 判断是否是null
variable === null
// typeof null会返回"object"
- 引用类型检测
variable instanceof Object
variable instanceof RegExp
variable instanceof Array
// instanceof操作符会返回布尔值
instanceof
操作符,左边必须是引用类型值(对象),右边必须是函数(构造函数),判断的原则是右侧的构造函数的prototype
属性是否在左侧对象的原型链上,如是则返回true,否则返回false。注意不同的window之间不能用instanceof检测对象。
对于原始类型来说,想直接通过 instanceof 来判断类型是不行的,当然还是有办法让 instanceof 判断原始类型
class PrimitiveString {
static [Symbol.hasInstance](x) {
return typeof x === 'string'
}
}
console.log('hello world' instanceof PrimitiveString) // true
Symbol.hasInstance是一个能让我们自定义 instanceof
行为的东西,以上代码等同于 typeof 'hello world' === 'string'
,所以结果自然是 true 了。这其实也侧面反映了一个问题, instanceof 也不是百分之百可信的。
Symbol.hasInstance
不仅可以直接挂在对象或类的静态属性上,也可以挂在对象的原型上(查找对象属性时对象本身找不到会沿原型链向上查)
var obj3 = {};
// undefined
1 instanceof obj3;
// Uncaught TypeError: Right-hand side of 'instanceof' is not callable
obj3.__proto__ = {
[Symbol.hasInstance](x) {
return typeof x === 'string';
}
};
1 instanceof obj3;
// false
'1' instanceof obj3;
// true
var obj4 = {};
// undefined
Object.prototype[Symbol.hasInstance] = function (x) {
return typeof x === 'string';
}
1 instanceof obj4;
// false
- 还有一个相当好用的检测类型方法
Object.prototype.toString.apply()Object.prototype.toString.call()
Object.prototype.toString.apply(undefined); // "[object Undefined]"
Object.prototype.toString.apply(null); // "[object Null]"
Object.prototype.toString.apply(3); // "[object Number]"
Object.prototype.toString.apply(''); // "[object String]"
Object.prototype.toString.apply([]); // "[object Array]"
Object.prototype.toString.apply(function(){}); // "[object Function]"
Object.prototype.toString.apply(/a/); // "[object RegExp]"
Object.prototype.toString.apply(new Date); // "[object Date]"
Object.prototype.toString.apply({}; // "[object Object]"
注意es5以下的引擎,null和undefined会返回"[object Object]"
在es6中Object.prototype.toString
的返回值可能被修改
({[Symbol.toStringTag]: 'Foo'}.toString())
// "[object Foo]"
类型转换
转布尔值
在js中会被转换为false的有undefined, null, false, NaN, '', 0, -0
转字符串
布尔值/数字/undefined/null/symbol/bigInt,转字符串都是直接变成字符串类型。
String('false') === 'false'
String('null') === 'null'
String('undefined') === 'undefined'
String(12) === '12'
String(Symbol('xxx')) === 'Symbol(xxx)'
数组转字符串相当于调用join(',')
函数
String([1, 2]) === '1,2'
转number
Number(false) === 0;
Number(true) === 1;
Number(null) === 0;
Number.isNaN(Number(undefined)) // true;
Number(Symbol('xxx')) // Uncaught TypeError:Cannot convert a Symbol value to a number
Number(9007199254740993n) // 9007199254740992(2^53)
// 字符串
Number('123') === 123;
Number.isNaN('123a') // true
// 数组
Number([]) === 0;
Number([1]) === 1;
Number(['1']) === 1;
Number.isNaN(Number([1, 2])) // true
// 对象
Number.isNaN(Number({})); // true
// 注意在chrome中 {} + 1 // 1,这是因为大括号会被认为是代码段
对象转原始类型
对象在转换类型的时候,会调用内置的 [[ToPrimitive]] 函数,对于该函数来说,算法逻辑一般来说如下:
- 如果已经是原始类型了,那就不需要转换了
- 如果需要转字符串类型就调用 x.toString(),转换为基础类型的话就返回转换的值。不是字符串类型的话就先调用 valueOf,结果不是基础类型的话再调用 toString
- 调用 x.valueOf(),如果转换为基础类型,就返回转换的值
- 如果都没有返回原始类型,就会报错
Symbol.toPrimitive
方法在转原始类型时调用优先级最高。
let a = {
valueOf() {
return 0
},
toString() {
return '1'
},
[Symbol.toPrimitive]() {
return 2
}
}
1 + a // => 3
四则运算符
加号运算符
- 运算中其中一方为字符串,那么就会把另一方也转换为字符串
- 如果一方不是字符串或者数字,那么会将它转换为数字或者字符串
注意优先级,一方不是字符串或数字的话会先转为数字,其次是字符串
1 + '1' // '11'
true + true // 2
4 + [1,2,3] // "41,2,3"
其他四则运算符
- 只要其中一方是数字,那么另一方就会被转为数字
关系操作符
相等操作符
基本比较流程如上图,对于==
操作符,最常用的就是判断一个变量是否为null或undefined。
[] == ![]
// true
按运算符优先级,![]为false。转为比较[] == false
,按照流程,布尔值转为Number。转为比较[] == 0
,对象转原始类型,转为比较'' == 0
,字符串转Number,转为比较0 == 0
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!