类型进阶

时间:2021-2-20 作者:admin

类型转换

隐式类型转换: 隐式转换就是系统默认的、不需要加以声明就可以进行的转换

数字和字符串 +操作时,数字会隐式转换成字符串 ,进行其他运算符操作时,字符串会隐式转换成数字
数字和字符串进行 . 操作时,会转换成对象类型
在+运算中,[]会转换成”,[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函数的属性,指向
语言内部使用的方法或者属性,通过他们可以改变语言的原生行为,感兴趣的可以自行研究一下

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。