类型转换
隐式类型转换: 隐式转换就是系统默认的、不需要加以声明就可以进行的转换
数字和字符串 +操作时,数字会隐式转换成字符串 ,进行其他运算符操作时,字符串会隐式转换成数字
数字和字符串进行 . 操作时,会转换成对象类型
在+运算中,[]会转换成'',[1]会转换成'1'
""转化成Boolean时结果为false
带有非数字字符的转换成数字都是NAN
NAN转换成boolean结果都是false
所有对象转换成boolean都是true
所有对象转换成数字都是NAN
console.log(1 + "px");
console.log("5" - "2"); //3
console.log(+'abc') //NAN
console.log(+ ' 123') //123
console.log(null + 1); //1
console.log(undefined + 1); //NAN
console.log([] + []); //''
console.log([1] + [2]); //'12'
console.log({} + 1); // [object Object]1
console.log({} - 1); //NAN
console.log(5-2 + "a"); //3a
在使用==的运算中,也会进行隐式类型转换,
console.log(null == undefined, "0" == 0, 0 == false, "0" == false) //true
显示类型转换:利用强制类型转换运算符进行转换
显示类型转换,可以是代码变得清晰易读,推荐在实际编码中使用,最简单的方法就是使用Boolean() Number() String() Object()
类型判断
1 typeof
可以用来判断除了null 之外的所有原始数据类型,不是判断复杂数组类型和null(都返回 object)
2 instanceof
无法识别原始数据类型,要注意 虽然typeof null 返回的时object 但是null 并不是object的实例
console.log(null instanceof Object,[] instanceof Array, [] instanceof Object); //false true true
3 constructor
可以检测变量的构造函数,也可以检测自定义的类型,null和undefined 没有这个方法
console.log({}.constructor.name,[].constructor.name ) //Object Array
function Foo() {}
console.log(new Foo().constructor.name); //Foo
4 Object.prototype.toString.call()
检测对象的内部属性 [[Class]] 不可以检测自定义的类型
console.log(Object.prototype.toString.call({})); //[object Object]
JS没有完美的识别数据类型的方法,需要结合情况使用
模板字符串
模板字符串支持所有的合法的js表达式,包括函数调用,也可以嵌套使用
function fn() {
return true;
}
let a = "tom";
console.log(`${fn() ? `${a}` : ""}`); //tom
模板字面量 最前面可以跟一个函数,这个函数叫模板字符串的tag
function myTag(strings, personExp, ageExp) {
let str0 = strings[0];
let str1 = strings[1];
//最后还有一项,但是是空字符串
//let str2=strings[2] //''
let ageStr;
if (ageExp > 99) {
ageStr = "centenarian";
} else {
ageStr = "youngster";
}
return str0 + personExp + str1 + ageStr;
}
let person = "tom";
let age = 18;
console.log(myTag`that ${person} is a ${age}`); //that tom is a youngster
Symbol
给对象创建属性的时候,不管该属性取什么名字,理论上都存在冲突的可能性,而是用symbol作为对象的属性 就没有这个问题,因为每一个symbol的值是不想等的,他的值是唯一的,也就意味着给对象添加私有属性成为了可能
let tom =symbol('key')
let jerry =symbol('key')
tom===jerry //false
let obj = {};
obj[tom] = "aa";
obj[jerry] = "aa";
console.log(obj); //{Symbol(key): "aa", Symbol(key): "aa"}
如果想要在不同的地方使用同一个symbol的时候,可以使用symbol.for方法
let uid = Symbol.for("uid");
let uid2 = Symbol.for("uid");
console.log(uid2 === uid); //true
let obj = {
[uid]: "123",
};
console.log(obj[uid], obj[uid2]); //123 123
可以用symbol.keyFor()方法 查找和某个symbol关联的key 值 (只能找到symbol.for生成的)
let uid = Symbol.for("uid");
console.log(Symbol.keyFor(uid)); //uid
let uid2 =Symbol('uid')
console.log(Symbol.keyFor(uid2)); //undefined
symbol不能转换成数字或者字符串 可以转换成布尔
let uid = Symbol("uid");
console.log(uid+'') //Uncaught TypeError: Cannot convert a Symbol value to a string
console.log(uid / 1); //Uncaught TypeError: Cannot convert a Symbol value to a number
console.log(!!uid) //true
对象的symbol属性使用Object.keys()或者getOwnProperty()都是获取不到的,需要使用getOwnPropertySymbols()
let id = Symbol.for("id");
let obj = {
[id]: "123",
name: "aa",
};
console.log(Object.keys(obj), Object.getOwnPropertyNames(obj)); //["name"]
console.log(Object.getOwnPropertySymbols(obj)) //[Symbol(id)]
es6内置了11个symbol,叫做well-Known symbol,他们都是symbol函数的属性,指向 语言内部使用的方法或者属性,通过他们可以改变语言的原生行为,感兴趣的可以自行研究一下