放肆青春的博客
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)

放肆青春

一个前端菜鸟的技术成长之路
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)
  • 前端

    • 前端 概览
    • 前端汇总

    • front 博文

    • front 项目总结

    • front 高级

    • front tools

  • vue

    • vue 概览
    • vue 汇总

    • vue 博文

    • vue 项目总结

    • vue 高级

  • html

    • html 概览
    • html 汇总

    • html 博文

  • css

    • css 概览
    • css 汇总

    • css 博文

    • sass

    • less

  • js

    • javascript 概览
    • JS 汇总

    • ES6

    • JS 博文

      • js 基础语法
      • js 数据类型
        • js 数据类型
          • 基本数据类型和引用数据类型的区别
          • String 和 new String 的区别
          • Symbol
          • bigint
          • 大整数
          • 浮点数
        • js 检测数据类型的几种方法
          • 1. typeof
          • 2. instanceof
          • 3. Object.prototype.toString.call(value)(最好的)
          • 4. Array.isArray
          • 5. 判断是不是 NaN
        • js 类型转换机制
          • parseInt
          • 对象转原始类型
          • 四则运算符
          • 比较运算符
        • 常见 js 类型判断
          • !!双感叹号
          • ===
          • undefined == null
          • null 和 undefined 区别
          • 为什么 null 的 typeof 是 object
          • Number.isNaN 与 isNaN 的区别
          • 字符串数字比较
          • 加法运算
      • js 字符串
      • js 数组
      • js 对象
      • js 变量
      • js 函数
      • js 事件
      • js 循环
      • js 浅拷贝和深拷贝
      • js 动画
      • js DOM
      • js 防抖节流
      • js 原型及原型链
      • js this
      • js 作用域
      • js 继承
      • js 闭包
      • js 内存
      • js垃圾回收
    • JS 工具

  • node

    • node 概览
    • node 汇总

    • node 框架

    • node 博文

  • react

    • react 概览
    • react 汇总

    • react 博文

    • react 高级

  • 微信小程序

    • 微信小程序 概览
    • 微信小程序总结
    • 微信小程序文章
    • 微信小程序 博文

    • 微信小程序 高级

  • 微信公众号

    • 微信公众号 概览
    • 微信公众号总结
    • 微信公众号文章
  • 多端开发

    • 多端开发
    • dsbridge 概览
    • jsbridge 概览
    • webview
    • uniapp

      • uniapp 概览
    • taro

      • taro 概览
    • flutter

      • flutter 概览
      • flutter 环境搭建
    • electron

      • electron 概览
  • front
放肆青春
2021-03-10

js 数据类型

# js 数据类型

值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol、bigint

引用数据类型:对象(Object)、数组(Array)、函数(Function)。

Number 基本类型可以精确表示的最大整数是 2^53

对于基本类型,赋值(=)是值的拷贝,比较(===)的是实际的值,

对于引用类型(Array 也是一种 Object),赋值(=)是引用地址的拷贝,比较(===)的是引用地址:

# 基本数据类型和引用数据类型的区别

  1. 存储位置不同

基本数据类型:存储在栈(stack)中

引用数据类型:引用地址存储在栈(stack)中,对象本身的值存储在内存堆

  1. 访问机制不同

基本数据类型:按值访问

引用数据类型:按引用访问

  1. 复制变量时的不同

基本数据类型:复制值

引用数据类型:复制的是内存地址,两个中任何一个作出的改变,另一个就会同时改变

  1. 参数传递的不同

基本数据类型:按值传递

引用数据类型:按内存地址传递,函数内部对这个参数的修改会体现在外部,它们都指向同一个对象

# String 和 new String 的区别

三个基本包装类的创建方式:

  1. 字面量:var str1 = 'hello world'  ==>  基本数据类型字符串

  2. 声明:var str2 = String('hello world')  ==>  基本数据类型字符串

  3. 表达式(new):var str3 = new String('hello world')  ==>  引用数据类型字符串对象(注意:是对象!!!)

结论:str1 === str2 // true,str1 === str3 // false 对象和基本类型值不相等

# Symbol

作用:

  1. 可以用来表示一个独一无二的变量防止命名冲突

  2. 还可以利用 symbol 不会被常规的方法(除了 Object.getOwnPropertySymbols 外)遍历到,所以可以用来模拟私有变量。

概念:表示独一无二的值

语法:let sym = Symbol(); Symbol 值通过 Symbol 函数生成

注意:

  1. Symbol 函数前不能使用 new 命令,这是因为生成的 Symbol 是一个原始类型的值,不是对象

  2. Symbol 值不能与其他类型的值进行运算,会报错 如:"your symbol is " + sym

  3. Symbol 值可以显式转为字符串。如:String(sym) // 'Symbol(My symbol)' 或者sym.toString() // 'Symbol(My symbol)'

  4. Symbol 值作为键名,不会被常规方法遍历得到

Symbol 作为属性名,遍历对象的时候,该属性不会出现在 for...in、for...of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。

Object.getOwnPropertySymbols()方法,可以获取指定对象的所有 Symbol 属性名。该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。

  1. 使用同一个 Symbol 值,Symbol.for()
let s1 = Symbol.for("foo");
let s2 = Symbol.for("foo");

s1 === s2; // true
1
2
3
4

# bigint

可以表示任意大的整数,BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。

BigInt() 不是构造函数,因此不能使用 new 操作符。

语法:BigInt(value); value: 创建对象的数值。可以是字符串或者整数。

除了通过 BigInt(),我们还可以通过在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n

let valA = 10n;
let valB = BigInt(10);

console.log(valA === valB); // true

10n == 10; // true
1
2
3
4
5
6

# BigInt 和 Number

因为隐式类型转换可能丢失信息,所以不允许在 bigint 和 Number 之间进行混合操作。当混合使用大整数和浮点数时,结果值可能无法由 BigInt 或 Number 精确表示。

10n + 1; // Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
Math.max(2n, 4n, 6n); // TypeError...
1
2

# BigInt 和 String

难免会遇到数字和字符串的转换,BigInt 也不例外,不过可惜的是 BigInt 转为 String 时,其标志性的 n 会被省略

String(10n); // '10'
"" + 11n; // '11'
1
2

# 大整数

JS 超过 53 个二进制位的数值,无法保持精度

JS 大于或等于 2 的 1024 次方的数值,JavaScript 无法表示,会返回 Infinity。

// 超过 53 个二进制位的数值,无法保持精度
Math.pow(2, 53) === Math.pow(2, 53) + 1; // true

// 超过 2 的 1024 次方的数值,无法表示
Math.pow(2, 1024); // Infinity
1
2
3
4
5

在(-2^53, 2^53)不包含边界范围内,双精度数表示和整数是一对一的,在这个范围以内,所有的整数都有唯一的浮点数表示,这叫做安全整数。

Number.MAX_SAFE_INTEGER 常量表示在 JavaScript 中最大的安全整数(maxinum safe integer)(2^53 - 1)9007199254740991

Number.MIN_SAFE_INTEGER 常量 代表在 JavaScript 中最小的安全的 integer 型数字(-(2^53 - 1))-9007199254740991

大数相加:

function add(a, b) {
  // 取两个数字的最大长度
  let maxLength = Math.max(a.length, b.length);
  // 用 0 去补齐长度
  a = a.padStart(maxLength, 0); // "00000000000003782647863278468012934670"
  b = b.padStart(maxLength, 0); // "23784678091370408971329048718239749083"
  // 定义加法过程中需要用到的变量
  let t = 0;
  let f = 0; // "进位"
  let sum = "";
  for (let i = maxLength - 1; i >= 0; i--) {
    t = parseInt(a[i]) + parseInt(b[i]) + f;
    f = Math.floor(t / 10);
    sum = (t % 10) + sum;
  }
  if (f == 1) {
    sum = "1" + sum;
  }
  return sum;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 浮点数

JS 采用 IEEE 754 双精度版本(64 位),JavaScript 所有数字都保存成 64 位浮点数

计算机基础:

  1. 计算机将所有数据以二进制的形式存储

  2. 计算机用有限的大小来存储数据(因为现实生活中不存在无限大的内存或硬盘)

  3. 单精度浮点数 float 总共包含 32 位,其中 1 位表示符号、8 位表示指数,最后 23 位表示小数;

  4. 双精度浮点数 double 总共包含 64 位,其中 s(sign) 1 位表示符号,e(exponent) 11 位表示指数,最后 m(mantissa) 52 位表示小数

  5. JavaScript 中数字的存储机制 (s) _ (m) _ (2^e)

问题:为什么 JS 中 0.1+0.2 != 0.3 ? // 0.1 + 0.2 = 0.30000000000000004

对于十进制转二进制,整数部分除二取余,倒序排列,小数部分乘二取整,顺序排列

0.1 转化为二进制 0.0 0011 0011 0011 0011 0011 0011 … (0011 循环)

0.2 转化为二进制 0.0011 0011 0011 0011 0011 0011 0011 … (0011 循环)

原因:计算机将所有数据以二进制的形式存储,并且存储空间有限,十进制小数转为二进制小数的过程中,会损失精度(计算机会舍弃后面的数值)

解决方案:

  1. 第三方库 BigNumber.js

  2. 将浮点数转化成整数计算

计算结果:

// 0.1
e = -4;
m = 1.1001100110011001100110011001100110011001100110011010 (52位)

// 0.2
e = -3;
m = 1.1001100110011001100110011001100110011001100110011010 (52位)

//这里的m指的是小数点后的52位,e为m的指数,小数点前的整数部分就是隐藏位s来表示符号
//如果发现指数e不一致时,一般采用右移,因为即使右边溢出了,损失的精度远远小于左移时的溢出
//转化之后进行求和

e = -3; m = 0.1100110011001100110011001100110011001100110011001101 (52位)
+
e = -3; m = 1.1001100110011001100110011001100110011001100110011010 (52位)
// 得到
e = -3; m = 10.0110011001100110011001100110011001100110011001100111 (52位)
// 保留一位整数
e = -2; m = 1.00110011001100110011001100110011001100110011001100111 (53位)
// 发现超过了52位,于是要做四舍五入,因为无法区分哪个更接近,于是规则是保留偶数的一个,得到最终的二进制数
m=1.0011001100110011001100110011001100110011001100110100 (52位)
// 然后得到最终的二进制数
1.0011001100110011001100110011001100110011001100110100 * 2^-2 = 0.010011001100110011001100110011001100110011001100110100
// 现在转化为十进制,二进制小数转化为十进制的方法是小数点后 第一位 *2 ^ -1,第二位 *2 ^ -2,以此类推
// 可以利用等比数列求和公式,最终求得十进制数为0.30000000000000004

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

# js 检测数据类型的几种方法

# 1. typeof

typeof 会返回一个变量的基本类型

主要能判断'number','boolean','string','undefined','symbol', 'bigint','function','object',八种数据类型

typeof 对于原始类型来说,除了 null 都可以显示正确的类型

typeof 1; // 'number'
typeof "1"; // 'string'
typeof undefined; // 'undefined'
typeof true; // 'boolean'
typeof Symbol(); // 'symbol'
1
2
3
4
5

typeof 对于对象来说,除了函数都会显示 object,所以说 typeof 并不能准确判断变量到底是什么类型

typeof []; // 'object'
typeof {}; // 'object'
typeof console.log; // 'function'
1
2
3

缺点:

(1)不能判断变量具体的数据类型比如数组、正则、日期、对象,因为都会返回 object,

(2)判断 null 的时候返回的是一个 object,这是 js 的一个缺陷,判断 NaN 的时候返回是 number

typeof 原理

typeof 原理: 不同的对象在底层都表示为二进制,在 Javascript 中二进制前(低)三位存储其类型信息。

  • 000: 对象
  • 010: 浮点数
  • 100:字符串
  • 110: 布尔
  • 1: 整数

typeof null 为"object"的 原因是因为 不同的对象在底层都表示为二进制,在 Javascript 中二进制前(低)三位都为 0 的话会被判断为 Object 类型,null 的二进制表示全为 0,自然前三位也是 0,所以执行 typeof 时会返回"object"。

# 2. instanceof

instanceof 返回的是一个布尔值

缺点:

  1. 检测不了 number,boolean,string

  2. instanceof 不能检测来自 iframe 的数组

instanceof 是判断类型的 prototype 是否出现在对象的原型链中,但是对象的原型可以随意修改,所以这种判断并不准确。

const obj = {};
obj.__proto__ = Array.prototype;
// Object.setPrototypeOf(obj, Array.prototype)
obj instanceof Array; // true
1
2
3
4

# 3. Object.prototype.toString.call(value)(最好的)

在 Number、String、Boolean、Array、Function、RegExp...这些类的原型上都有一个 toString 方法:这个方法就是把本身的值转化为字符串

(12).toString()//'12'

(true).toString()//'true'

[12,23].toString()//'12.23'

在 Object 这个类的原型上也有一个方法 toString,但是这个方法并不是把值转换成字符串,而是返回当前值得所属类详细信息,固定结构:'[object 所属的类]'

var obj = { name: "珠穆朗玛峰" };
obj.toString(); //[object Object]
1
2

想知道谁的所属类信息,我们就把这个 toString 方法执行,并且让 this 变为我们检测的这个数据值,那么方法返回的结果就是当前检测这个值得所属类信息

Object.prototype.toString.call(12)//[object Number]

缺点:Object.prototype.toString.call() 不能校验自定义类型

function Animal() {}
let a = new Animal();
Object.prototype.toString.call(a);
("[object Object]");
1
2
3
4

# 4. Array.isArray

判断是否为数组 Array.isArray([]) // true

Array.isArray()是 ES5 新增的方法,当不存在 Array.isArray() ,可以用 Object.prototype.toString.call() 实现。

当检测 Array 实例时,Array.isArray 优于 instanceof ,因为 Array.isArray 可以检测出 iframes

var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length - 1].Array;
var arr = new xArray(1, 2, 3); // [1,2,3]

// Correctly checking for Array
Array.isArray(arr); // true
Object.prototype.toString.call(arr); // true
// Considered harmful, because doesn't work though iframes
arr instanceof Array; // false
1
2
3
4
5
6
7
8
9
10

# 5. 判断是不是 NaN

(1) Object.is var c = NaN; Object.is(c, NaN) // true

(2) NaN 是唯一一个不等于任何自身的特点

function isNaN(n) {
  if (n !== n) {
    return true;
  } else {
    return false;
  }
}
1
2
3
4
5
6
7

(3) typeof(n) === "number" && isNaN(n)

hasOwnproperty 检测当前属性是否为对象的私有属性

# js 类型转换机制

常见的类型转换有:

  1. 强制转换(显示转换)

显示转换,即我们很清楚可以看到这里发生了类型的转变,常见的方法有:

Number() , parseInt(),String(),Boolean()

  1. 自动转换(隐式转换)

可以归纳为两种情况发生隐式转换的场景:

(1)比较运算(==、!=、>、<)、if、while 需要布尔值地方

(2)算术运算(+、-、*、/、%)


在 JS 中类型转换只有三种情况:

(1) 转换为布尔值

在条件判断时,除了 undefined, null, false, NaN, '', 0, -0,其他所有值都转为 true,包括所有对象。

(2) 转换为数字

(3)转换为字符串

image

# parseInt

语法:parseInt(string, radix) 如果 radix 在 2-36 之外会返回 NaN。

在没有指定基数,或者基数为 0 的情况下,JavaScript 作如下处理:

(1) 如果字符串 string 以"0x"或者"0X"开头, 则基数是 16 (16 进制).

(2) 如果字符串 string 以"0"开头, 基数是 8(八进制)或者 10(十进制),那么具体是哪个基数由实现环境决定。ECMAScript 5 规定使用 10,但是并不是所有的浏览器都遵循这个规定。因此,永远都要明确给出 radix 参数的值。

(3) 如果字符串 string 以其它任何值开头,则基数是 10 (十进制)。

  1. 实例:['1','2','3'].map(parseInt) [1, NaN, NaN]

(1) parseInt('1', 0); // 1 (parseInt 的处理方式,这个地方 item 没有以"0x"或者"0X"开始,8 和 10 这个基数由实现环境来定,ES5 规定使用 10 来作为基数,因此这个 0 相当于传递了 10)

(2) parseInt('2', 1); // NaN (因为 parseInt 的定义,超出了 radix 的界限)

(3) parseInt('3', 2); // NaN (虽然没有超出界限,但是二进制里面没有 3,因此返回 NaN)

  1. 实例:['10', '10', '10', '10', '10'].map(parseInt) [10, NaN, 2, 3, 4]

# 对象转原始类型

对象在转换类型的时候,会调用内置的 [[ToPrimitive]] 函数,对于该函数来说,算法逻辑一般来说如下:

  1. 如果已经是原始类型了,那就不需要转换了

  2. 调用 x.valueOf(),如果转换为基础类型,就返回转换的值

  3. 调用 x.toString(),如果转换为基础类型,就返回转换的值

  4. 如果都没有返回原始类型,就会报错

# 四则运算符

加法运算符不同于其他几个运算符,它有以下几个特点:

  1. 运算中其中一方为字符串,那么就会把另一方也转换为字符串

  2. 如果一方不是字符串或者数字,那么会将它转换为数字或者字符串

1 + "1"; // '11'
true + true; // 2
4 + [1, 2, 3]; // "41,2,3"
1
2
3

另外对于加法还需要注意这个表达式 'a' + + 'b'

'a' + + 'b' // -> "aNaN"

因为 + 'b' 等于 NaN,所以结果为 "aNaN",你可能也会在一些代码中看到过 + '1' 的形式来快速获取 number 类型。

数字(Number)/字符串(String)以外的原始类型相加:

/**
 * 数字(Number)/字符串(String)以外的原始类型相加
 */
console.log(true + true); // 2
console.log(true + null); // 1
console.log(true + undefined); //NaN
console.log(undefined + null); //NaN
console.log(undefined + undefined); //NaN
console.log(null + null); //0
1
2
3
4
5
6
7
8
9

当数字与字符串以外的,其他原始数据类型直接使用加号运算时,就是转为数字再运算,这与字符串完全无关。

那么对于除了加法的运算符来说,只要其中一方是数字,那么另一方就会被转为数字

4 * "3"; // 12
4 * []; // 0
4 * [1, 2]; // NaN
1
2
3

# 比较运算符

  1. 如果是对象,就通过 toPrimitive 转换对象

  2. 如果是字符串,就通过 unicode 字符索引来比较

let a = {
  valueOf() {
    return 0;
  },
  toString() {
    return "1";
  },
};
a > -1; // true
1
2
3
4
5
6
7
8
9

在以上代码中,因为 a 是对象,所以会通过 valueOf 转换为原始类型再比较值。

# 常见 js 类型判断

# !!双感叹号

能判断返回 false 的七个值:undefined,null,"",-0,0,NaN,false

用两个!!就可以将变量转化为对应布尔值。

# ===

=== 不能判断以下情况:+0 === -0(true),NaN === NaN (false),需要用Object.is

# undefined == null

console.log( undefined == null ) //true

console.log( undefined === null ) //false

Javascript 规范: 要比较相等性之前,不能将 null 和 undefined 转换成其他任何值,并且规定 null 和 undefined 是相等的。

null 和 undefined 都代表着无效的值。

强制转换为布尔类型,两者都是 false

强制转换为数值,undefined 返回的是 NaN,null 返回的是 0。用 isNaN() 验证,undefined 不是数字,null 是数字。

比较操作符 == 不会自动转换 undefined 和 null

// 操作符 `==` 不会自动转换 undefined 和 null
undefined == false; // false
undefined == true; // false
null == false; // false
null == true; // false

undefined == 0; // false
null == 0; // false

// 操作符会自动转换其他值为数值
true == 1; // true
true == 2; // false
1
2
3
4
5
6
7
8
9
10
11
12

# null 和 undefined 区别

null 表示"没有对象",即该处不应该有值。典型用法是:

(1) 如果定义的变量在将来用于保存对象,那么最好将该变量初始化为 null,而不是其他值。

(2) 当一个数据不再需要使用时,我们最好通过将其值设置为 null 来释放其引用

(3) 作为对象原型链的终点。

undefined 表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:

(1)变量被声明了,但没有赋值时,就等于 undefined。 var data; console.log(data === undefined); //true

(2) 调用函数时,应该提供的参数没有提供,该参数等于 undefined。

(3)对象没有赋值的属性,该属性的值为 undefined。

(4)函数没有返回值时,默认返回 undefined。

# 为什么 null 的 typeof 是 object

这是一个存在很久了的 Bug

因为在 JS 的最初版本中,使用的是 32 位系统,为了性能考虑使用低位存储了变量的类型信息,000 开头代表是对象,然而 null 表示为全零,所以将它错误的判断为 object 。虽然现在的内部类型判断代码已经改变了,但是对于这个 Bug 却是一直流传下来。

# Number.isNaN 与 isNaN 的区别

Number.isNaN 不存在类型转换的行为

isNaN:isNaN 会通过 Number 方法,试图将"参数"转换成 Number 类型,如果转换失败,返回 true

Number.isNaN:Number.isNaN 只是严格的判断传入的参数是否全等于 NaN

//isNaN
console.log(isNaN(null)); //false
console.log(isNaN(true)); //false
console.log(isNaN(false)); //false
console.log(isNaN(0)); //false
console.log(isNaN(undefined)); //true
console.log(isNaN("AB")); //true
console.log(isNaN({ a: 1 })); //true
console.log(isNaN(NaN)); //true

//Number.isNaN
console.log(Number.isNaN(null)); //false
console.log(Number.isNaN(true)); //false
console.log(Number.isNaN(false)); //false
console.log(Number.isNaN(0)); //false
console.log(Number.isNaN(undefined)); //false
console.log(Number.isNaN("AB")); //false
console.log(Number.isNaN({ a: 1 })); //false
console.log(Number.isNaN(NaN)); //true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 字符串数字比较

//1.数字比较
console.log("数字比较:" + (12 < 3)); //false
//2.字符串数字和数字比较 统一转换成数字进行比较
console.log("字符串数字和数字比较:" + (11 < "5")); //false
//3.字符串和数字进行比较 字符串为非纯数字时,则将非数字字符串转成数字的时候会转换为NaN,当NaN和数字比较时不论大小都返回false.
console.log("字符串和数字进行比较:" + (11 > "FlyElephant")); //false
console.log("字符串和数字进行比较:" + (11 < "FlyElephant")); //false
//4.字符串数字比较 转换成ASCII码比较
console.log("字符串数字比较:" + ("11" < "5")); //true
console.log("11".charCodeAt()); //49
console.log("5".charCodeAt()); //53
//5.字符串比较 转换成ASCII码进行比较
console.log("字符串比较:" + ("博客园" < "FlyElephant"));
console.log("博客园".charCodeAt()); //21338
console.log("FlyElephant".charCodeAt()); //70
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 加法运算

// 数字(Number)/字符串(String)以外的原始类型相加转为数字再运算
console.log(true + true); // 2
console.log(true + null); // 1
console.log(true + undefined); //NaN
console.log(undefined + null); //NaN
console.log(undefined + undefined); //NaN
console.log(null + null); //0

console.log([] + []); //""
console.log({} + {}); //"[object Object][object Object]"
console.log({} + []); //"[object Object]"

// 一元加号运算时,唯一的运算元相当于强制求出数字值的Number([])运算
console.log(+[]); // 0
console.log(+{}); // NaN
console.log(+null); //0
console.log(+true); //1
console.log(+undefined); //NaN
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

参考:JS 加法运算全解析 (opens new window)

更新时间: 1/27/2022, 6:22:25 PM
js 基础语法
js 字符串

← js 基础语法 js 字符串→

最近更新
01
前端权限管理
02-24
02
vue2指令
02-24
03
vue2 hook
02-24
更多文章>
Theme by Vdoing | Copyright © 2019-2022 放肆青春
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式