MarginLon MarginLon
首页
  • Web

    • Web基础
    • Web布局
    • CodeSnippet
  • Vue

    • Vue
  • React

    • React
  • Node.js

    • Node.js
  • 技术文档
  • UI组件库
  • 动画库
  • 图形库
  • 桌面端
  • 学习笔记
  • 生活笔记
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

MarginLon

http://info.cern.ch
首页
  • Web

    • Web基础
    • Web布局
    • CodeSnippet
  • Vue

    • Vue
  • React

    • React
  • Node.js

    • Node.js
  • 技术文档
  • UI组件库
  • 动画库
  • 图形库
  • 桌面端
  • 学习笔记
  • 生活笔记
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 数据类型 类型检测 类型转换
    • 1. 数据类型
      • 原始值
      • number
      • string
      • boolean
      • null
      • undefined
      • BigInt
      • Symbol
      • 引用值(对象类型)
    • 2. 类型检测
      • typeof 运算符
      • [example] instanceof [class] 实例是否属于构造函数(通过原型链)
      • [example].constructor===[class] 获取构造函数
      • Object.prototype.toString.call([value])
      • 快捷方法
    • 3. 类型转换
  • 精度问题
  • 堆栈内存 函数底层运行机制 块级作用域
  • GC机制 闭包作用域 let/const/var
  • 闭包应用
  • DOM
  • BOM
  • This指向
  • 浏览器渲染机制 CRP优化 事件循环机制
  • 函数防抖节流
  • 模块化 柯里化
  • 构造函数 原型
  • CLASS
  • 工厂设计模式 深浅拷贝 深浅合并
  • Iterator/Generator
  • Promise/ Async/ Await
  • HTTP/跨域
  • API
  • AJAX
  • 事件
  • 《JavaScript高级程序设计(第4版)》
MarginLon
2022-04-10
目录

数据类型 类型检测 类型转换

# 1. 数据类型

# 原始值

# number

// NaN 非有效数字、Infinity 无穷大
// Number.MIN_SAFE_INTEGER
// NaN == NaN false
// NaN === NaN false  => NaN !== NaN
// => isNaN([value]); 
// Object.is(NaN,NaN); true
1
2
3
4
5
6

# string

# boolean

# null

# undefined

# BigInt

/*
  BigInt:
    Number
*/
1
2
3
4

# Symbol

// 1. 对象的唯一属性名 (属性名类型:string && symbol && Map允许属性名是对象)
//console.log(Symbol()===Symbol()); // false

let key = Symbol();
let obj1 = {
      [key]:100
    };
console.log(obj1[key]);

let obj2 = {
      [Symbol()]:100
    };
let arr = Object.getOwnPropertySymbols(obj);
  arr.forEach(key=>{
    console.log(obj2[key]);
  });

//2. redux/vuex公共状态管理,派发的行为标识基于symbol类型宏管理

//3. Symbol.hasInstance\toStringTag\toPrimitive\iterator\asyncIterator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 引用值(对象类型)

  • 标准普通 {num:100}
  • 标准特殊 [10,20] /\d+/ new Date()
  • 非标准特殊 new Number(10)
  • 函数对象(实现了call方法) function fn(){}
new Symbol() // TypeError
new BigInt() // TypeError: Not a constructor
Object(Symbol()) // pass 
1
2
3

# 2. 类型检测

# typeof 运算符

  • 返回字符串

  • null -> 'object'

  • 实现CALL的对象[函数、箭头函数、生成器函数、构造函数] -> 'function'

  • 未实现CALL的对象 -> 'object'

  • 未声明的变量 -> 'undefined'

  • 需求:验证val是否为一个对象

    if(val!==null && /^(object|function)$/i.test(typeof val)){
    
    }
    
    1
    2
    3

# [example] instanceof [class] 实例是否属于构造函数(通过原型链)

  • 返回true/false
  • 细分Object
  • 无法检测标准普通对象
  • 无法检测原始值类型
  • 运行:
    1. class[Symbol.hasInstance]:只支持ES6中的class static重构
    2. example原型链查找class直到Object.prototype

# [example].constructor===[class] 获取构造函数

# Object.prototype.toString.call([value])

  • 返回结果: "[object ?]"

    1. example[Symbol.toStringTag]
    2. (Math => "[object Math]" GeneratorFunction Promise Set Map...)
    3. 没有此属性,则找构造函数
  • 标准普通对象=>字符串

    • JSON.stringify
    • Qs.stringify
  • 自定义构造函数 : "[object Object]"

    //需求:期望自定义构造函数:"[object 构造函数]"
    const Fn = function Fn(){}
    Fn.prototype[Symbol.toStringTag] = "Fn";
    let f = new Fn;
    console.log(Object.prototype.toString.call(f));
    
    1
    2
    3
    4
    5

# 快捷方法

  • Array.isArray([value])
  • isNaN

# 3. 类型转换

# Object => Number/String

  1. 检测Symbol.toPrimitive,获得原始值
  2. 第一步没有,valueOf获取原始值,不是原始值则继续第三步
  3. 第二步没有,调用toString,字符串
  4. 第三步后,若有需要,基于Number(),数字

# Others => Number

  • Number([val])
    • 隐式转换的调用方法(如isNaN(), ==, 数学运算)
    • 规则:
      • String:出现非有效数字字符即为NaN,空串为0
      • null:0
      • undefined:NaN
      • boolean:true==1 false==0
      • BigInt:去除n, 超过安全数字处理为科学计数法
      • Symbol->Uncaught TypeError: Cannot convert a Symbol value to a number
  • parseInt([val],[radix])/parseFloat([val])
    • [val] 必须是一个字符串,否则隐式转换
    • [radix] 不设置或为0,按照10处理,若字符串'0x'开头,按照16处理
    • 处理过程:在[val]中找到所有符合[radix]进制的内容,直到遇到不符合的字符,把找到的内容按照[radix]进制转换为10进制
    • [radix]范围:2~36,包括0,否则NaN
  • 隐式转换
    • inNaN()
    • 数学运算(特殊:"+"的字符串拼接)
    • "=="

# Others => String

  • 规则:
    • 原始值,其他对象用引号包含
    • 标准普通对象 => "[object Object]"
    • 标准非普通对象 => 字符串
    • JSON.stringify <=> JSON.parse
    • Qs.stringify <=>
  • 隐式转换:
    • '+':
      • 两边:出现字符串
      • 两边:出现对象
        • 按Object => Number/String处理, toString获取了字符串则拼接
      • 一边:左边为空
        • 数学运算

# Others => Boolean

  • 规则:只有0,NaN,null,undefined,""为false
  • ! !!
  • Boolean([val])
  • 循环或条件判断(隐式转换)
  • A||B A&&B
    • A && B
      • 如果第一个操作数是对象,则返回第二个数
      • 如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对象。
      • 如果两个操作数都是对象,则返回第二个数操作数。
      • 如果有一个操作数是null,则返回null。
      • 如果有一个操作数是NaN,则返回NaN。
      • 如果第一个操作数是undefined,则返回undefined。
      • 对于逻辑与,如果第一个操作数是false,无论第二个操作数是什么,结果都不可能再是true。
    • A || B
      • 如果第一个操作数是对象,则返第一个操作数
      • 如果第一个操作数的求值结果为false,则返回第二个操作数
      • 如果两个操作数都是对象,则返回第一个操作数
      • 如果两个操作数是null,则返回null
      • 如果两个操作数是NaN,则返回NaN
      • 如果两个操作数是undefined,则返回undefined

# "=="的规则

  • 类型相同
    • {}=={} :false 比较堆内存地址,地址相同则相等
    • []==[] :false
    • NaN==NaN :false Object.is(NaN, NaN) :true
  • 类型不同
    • null==undefined :true === :false null/undefined与其他类型不相等
    • 字符串==对象 对象=>字符串
    • 两边类型不一致,先转换为数字再比较

# 其它

  • "+"
    • {} + 0 左边{}视为代码块 // +0 => 0
    • ({} + 0) // "[object Object]0"
    • 0 + {} // "0[object Object]"
  • 模板字符串实现的是字符串拼接,对象转换为字符串,其余数学运算则对象=>数字

//var a = ?; 

//方案一:
var a ={
  i:0
};
a[Symbol.toPrimitive] = function toPrimitive(){
  //this -> a
  return ++this.i;
}

//方案二:
var a =[1,2,3];
a.toString = a.shift;

//方案三:
var i = 0;
Object.defineProperty(window,'a',{
  get(){
    return ++i;
  }
});

if(a==1 && a==2 && a==3){
  console.log('OK');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
编辑 (opens new window)
#JavaScript
上次更新: 2023/09/17, 23:41:49
精度问题

精度问题→

最近更新
01
KnockoutJS
11-12
02
综述
10-17
03
前言
10-12
更多文章>
Theme by Vdoing | Copyright © 2019-2024 MarginLon | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式