你不知道的JS(中卷)笔记——类型和语法总结

2020-03-04  本文已影响0人  李牧敲代码

本文目录

  1. JS的基本类型
  2. 特殊数值和数字
  3. 原生函数
  4. 强制类型转换
  5. 运算符
  6. try finally
  7. 类型判断及其原理和使用场景

JS的基本类型

  1. string
  2. number
  3. boolean
  4. object
  5. undefined
  6. null
  7. symbol

特殊数值和数字

  1. undefined可以作为表示符(能进行赋值),而null不可以,他们既是基本类型也可以作为值
  2. 判断NaN自身既可以用Number.isNaN也可以用自相等(NaN是JS中唯一一个自身不相等的值),不要用window.isNaN。
       let a = 2 / 'foo';
       let b = NaN;
       let c = 'foo';

       console.log(window.isNaN(c)) //true
       console.log(Number.isNaN(c)) // false
       console.log(Number.isNaN(b)) // true
       console.log(b === b ? false : true) //true
       console.log(Object.prototype.toString.call(b) === '[object Number]') //true

原生函数

常用的原生函数:
  1. String()
  2. Number()
  3. Boolean()
  4. Object()
  5. Date()
  6. Array()
  7. Error()
  8. Function
  9. RegExp()
  10. Symbol()
封装对象:

概念: 通过构造函数封装了基本值的对象称为封装对象。
封装对象包装: 指JS自动将基本数值包装成一个封装对象以便使用一些属性和方法。

        let a = '123';
        console.log(a.length) //3

如果想自己对基本数值进行包装可以用Object()(不带关键词new)

由于浏览器引擎自身的优化,没必要的情况不用使用封装对象,有时候还会踩坑。
比如:

let a = new Boolean(false)
console.log(!a === false)//true

强制类型转换

抽象值操作,即对字符串,数字,布尔值之间的类型转换:
1. toString:

常用方法:

  1. "" + value
  2. String(value)
  3. value.toString
  4. JSON.strinify(value)
    ps: 前两种可以处理null,undefined这些值,而第三种不可以,至于第四种通过JSON进行字符串化只能是安全的JSON值(除了undefined,function,symbol和循环引用的对象),在对象中会将其忽略,在数组中返回null

规则:

let obj = {
    a: undefined,
    b: function(){},
    c: Symbol(123)
}

let arr = [undefined, function(){}, Symbol(123)]
console.log(JSON.stringify(obj))//{}
console.log(JSON.stringify(arr))//[null, null, null]

2. toNumber
常用方法:

  1. Number(value)
  2. +value
  3. parseInt系列

规则:

let a = {
    valueOf: () => 1
}

let b = {
    toString: () => 2
}


let arr1 = [1,2]
arr1.valueOf = () => 123
console.log(Number(a))//1
console.log(Number(b))//2
console.log(Number(arr1))//123

3. toBoolean:
常用方法:

  1. Boolean(value)
  2. !!

规则:

js中所有可以强制转换为false的值就是假值,总共有以下几种:

  1. undefined
  2. -0, +0, NaN
  3. ""
  4. null

ps: 除了假值以外的值就是真值

运算符

||和三元运算符
三元运算符在条件成立的时候会多运算一边,而 || 不会,比如:

let index = 0;

function f1() {
    index++;
    console.log(index)
    return true
}
f1() ? f1(): fasle//1 2
f1() || false//3

try finally

try finally 语法中finally会在结果返回之前执行

function f1() {
    try {
        return 'f1的结果'
    }
    finally {
        console.log(123)
    }
}


console.log(f1())//123 f1的结果

类型判断及其原理和使用场景

常用的方法:

  1. typeof
  2. instanceof
  3. constructor
  4. Object.prototype.toString.call

【typeof】

返回结果有8种:

  1. ‘string’
  2. ‘number’
  3. ‘undefined’
  4. ‘function’
  5. ‘boolean’
  6. ‘object’
  7. 'symbol'
  8. 'bigint'

typeof 只有1种情况下会报错:
在const,let这些关键字申明的变量上面使用(‘暂存死区’)

console.log(typeof a);
let a;

实现原理:
js 在底层存储变量的时候,会在变量的机器码的低位1-3位存储其类型信息👉

000:对象
010:浮点数
100:字符串
110:布尔
1:整数
but, 对于 undefined 和 null 来说,这两个值的信息存储是有点特殊的。
null:所有机器码均为0
undefined:用 −2^30 整数来表示
【instanceof】

instanceof的实现原理就是通过右边的值是否存在左边的原型链上实现的。用代码就是这样表示:

let myInstanceof = function(value, type) {
    const right = type.prototype;
    let left = value.__proto__;

    while(true) {
        if(left === null) {
            return false
        }else if(left === right){
            return true
        }else {}
        left = left.__proto__;
    }
}

console.log(myInstanceof([], Array))

看几个有趣的例子:

function Foo() {
}

Object instanceof Object // true
Function instanceof Function // true
Function instanceof Object // true
Foo instanceof Foo // false
Foo instanceof Object // true
Foo instanceof Function // true

这里记住这样一条父子链:
Object.prototype(爷爷) => Function.prototype(爸爸) => Object和Function(儿砸)

所有具体对象默认的proto和函数默认的proto都分别指向Object.prototype和Function.prototype

当然除了原生的类型,你也可以通过Symbol.hasInstance自定义instance的行为

class obj {
    static [Symbol.hasInstance](instance) {
        return true
    }
}


console.log('scsdfd' instanceof obj)//true

constructor

返回创建实例对象的 Object构造函数的引用。注意,此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串.

Object.prototype.toString.call

对类型判断比较完善。
PS:
根据目前我掌握的情况来看,如果目标对象上存在Symbol.toStringTag属性,则将Symbol.toStringTag的值作为结果的一部分返回,否则继续从其原型上找到其类型返回。


let arr1 = [1,2,45];
let arr2 = []

arr1[Symbol.toStringTag] = '6666'

console.log(Object.prototype.toString.call(arr1))//[object 6666]
console.log(Object.prototype.toString.call(arr2))//[object Array]

参考

https://www.jianshu.com/p/c463eca929c2

[完]

上一篇 下一篇

猜你喜欢

热点阅读