数字与字符串的区别

功能不同

数字 字符串
加减乘除 ✔️
电话号码 ✔️

储存形式不同

数字 字符串
64 位浮点数 UCS-2

如何存数字

十进制转二进制即可。

为何用十六进制

二进制太慢了。

数据类型

  • 数字 number
  • bigint
  • 字符串 string
  • 布尔 bool
  • 符号 symbol
  • 空 undefined
  • 空 null
  • 对象 object
    • 数组
    • 函数
    • 日期

数字 number

写法

  • 整数:1
  • 小数:0.1
  • 科学记数法:1.23e4($1.23\times10^{3}$)
  • 二进制:0b11、0B11(3)
  • 八进制:0123、00123、0o123(83)
  • 十六进制:0x3F、0X3F(63)

特殊值

  • 零:0、+0、-0
  • 无穷大:Infinity、+Infinity、-Infinity
  • 无法表示的数:NaN(Not a Number),NaN 不等于 NaN

64 位浮点数

JS数字的存储形式:

  • 浮点就是浮动的点,意思就是小数点会乱动
  • 123.456 可以表示为 1.23456e10^2
  • 也可以表示为 12345.6e10^-2

64位存储一个 number:

  • 符号占 1 位
  • 指数占 11 位(-1023~1024)
  • 有效数字占 52 位(开头的 1 省略)

字符串 string

语法

1
2
3
4
5
'单引号'
"双引号"
`反引号`
`反引号
可以换行`

示例:it’s ok 的写法

1
2
3
4
5
6
7
// 错误写法
'it's ok'

// 正确写法
'it\'s ok'
"it's ok"
`it's ok`

转义

写法 含义
\' '
\" "
\\ \
\n 换行
\r 回车
\t 制表符 tab
\u4f60 「你」的 unicode 编码(4 个十六进制数)
\x48 前 256 个 unicode 字符(2 个十六进制数)

字符串长度

1
2
3
4
'123'.length    // 3
'\n\r\t'.length // 3
''.length       // 0
' '.length      // 1

读取字符串

1
2
3
4
5
// string[index]
let s = 'hello'
s[0] // 'h'
s[4] // 'o'
s[5] // undefined

布尔值 boolean

布尔值只有两种:true 和 false,falsy 为作布尔值判断时被认为 false 的值。

falsy 值

false 和 falsy 以外的值都为 true。

false The keyword false.
0 The Number zero (so, also 0.0, etc., and 0x0).
-0 The Number negative zero (so, also -0.0, etc., and -0x0).
0n The BigInt zero (so, also 0x0n). Note that there is no BigInt negative zero — the negation of 0n is 0n.
"", '', ```` Empty string value.
null null — the absence of any value.
undefined undefined — the primitive value.
NaN NaN — not a number.
document.all Objects are falsy if and only if they have the [[IsHTMLDDA]] internal slot.That slot only exists in document.all and cannot be set using JavaScript.

underfined 与 null

  • 都等于 falsy
  • 未赋值的变量为 underfined
  • 函数的默认 return 为 underfined

对象 object

对象是无序的键值(key, value)集合。

语法:

1
2
3
let obj1 = { name: "frank", age: 18 }; // 常规写法
let obj2 = new Object({ name: "frank" }); // 正规写法
console.log({ name: "frank", age: 18 }); // 无名的对象

细节:

  • 键名是字符串,不是标识符,可以包含任意字符

  • 引号可省略,省略之后就只能写标识符

  • 就算引号省略了,键名也还是字符串

  • 每个 key 都是对象的属性名(property)

  • 每个 value 都是对象的属性值

  • 若键不加引号,则运算后转为字符串

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    let obj = {
      1: "a",
      3.2: "b",
      1e2: true,
      1e-2: true,
      0.234: true,
      0xff: true,
    };
    console.log(obj);
    /* 输出
    {
      '1': 'a',
        '100': true,
        '255': true,
        '3.2': 'b',
        '0.01': true,
        '0.234': true
    }
     */
    
  • Object.keys(obj) 可打印 obj 的所有 key

变量做属性名

给属性名加括号就可以用变量:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
let a = "aaa";
let obj_a = {
  a: 1111,
};
console.log(obj_a);
// { a: 1111 }

let b = "bbb";
let obj_b = {
  [b]: 1111,
};
console.log(obj_b);
// { bbb: 1111 }

let obj_c = {
  [1 + 2 + 3 + 4]: "十",
};
console.log(obj_c);
// { '10': '十' }

删除属性

1
2
3
// 语法
delete object.property
delete object['property']
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var obj = {
  name: "Jack",
  age: 18,
};
console.log(obj);
// { name: 'Jack', age: 18 }
delete obj.name;
delete obj["name"];
console.log(obj);
// { age: 18 }

读取属性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 语法
Object.keys(object)    // 查看所有属性
Object.values(object)  // 查看所有属性值
Object.entries(object) // 查看所有属性与属性值
object                 // 查看所有属性与属性值
object.['key']         // 查看属性值
object.key             // 查看属性值
console.dir(object)    // 查看原型属性
object.__proto__       // 查看原型属性,不推荐
object.hasOwnProperty("property") // 检查属性是否为独有
"property" in object              // 检测对象是否包含属性名,无法区分独有还是公有
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 示例
var obj = {
  name: "jack",
  age: 18,
};
console.log(Object.keys(obj));
// [ 'name', 'age' ]
console.log(Object.values(obj));
// [ 'jack', 18 ]
console.log(Object.entries(obj));
// [ [ 'name', 'jack' ], [ 'age', 18 ] ]
console.log(obj);
// { name: 'jack', age: 18 }
console.log(obj["name"]); // jack
console.log(obj.name); // jack
console.log(obj.hasOwnProperty("name")); // true
console.log(obj.hasOwnProperty("toString")); // false
console.log("name" in obj); // true
console.log("gender" in obj); // false

增加与修改属性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// 直接赋值
let obj = { name: "frank" };
obj.name = "frank";
obj["name"] = "frank";
obj["na" + "me"] = "frank";
let key = "name"; obj[key] = "frank";

// 批量赋值
Object.assign(obj, {age: 18, gender: 'man'})

// 定义对象的原型
var common = {
  hairColor: "black",
  language: "Chinese",
};
let person = Object.create(common) // person 的原型是 common

原型

  • 每个对象都有原型
  • 原型里存着对象的共有属性
  • 比如 obj 的原型就是一个对象
  • obj.__proto__ 存着这个对象的地址
  • 这个对象里有 toString / constructor / valueOf 等属性

  • 对象的原型也是对象
  • 所以对象的原型也有原型
  • obj = {} 的原型即为所有对象的原型
  • 这个原型包含所有对象的共有属性,是对象的根
  • 这个原型也有原型,是 null

变量声明

声明与赋值:

1
2
3
4
var a = 1;
let a = 1;
const a = 1;
a = 1; // 赋值

let

1
let a = 1;

let 的特点:

  • 遵循块作用域,即使用范围不能超出 { }

    1
    2
    3
    4
    5
    
    {
      let b = 1;
      console.log(b); // 1
    }
    console.log(b); // 报错
    
  • 不能重复声明

    1
    2
    
    let a = 1;
    let a = 2; // 报错:SyntaxError: Identifier 'a' has already been declared
    
  • 声明时可赋值,可不赋值

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    // 不赋值
    let a;
    console.log(a); // undefined
    // 声明后赋值
    let b;
    b = 1;
    console.log(b); // 1
    // 声明时赋值
    let c = 2;
    console.log(c); // 2
    
  • 必须先声明再使用

    1
    2
    
    console.log(a); // 报错:ReferenceError: Cannot access 'a' before initialization
    let a = 1;
    
  • 全局声明的 var 不会变成 windows 属性

    1
    2
    3
    4
    5
    
    let abc = 'abc';
    window.abc; // undefined
      
    var abc = 'abc';
    window.abc; //'abc'
    

const

const 的全称是 constant(常量)。

const 的特点:

  • 和前面的 let 差不多

  • 不同之处:声明时必须赋值,赋值后不能改

    1
    2
    3
    4
    
    const a; // 报错:Uncaught SyntaxError: Missing initializer in const declaration
      
    const b = 1;
    b = 2; // 报错:Uncaught TypeError: Assignment to constant variable
    

类型转换

JavaScript Garden 有很多 JS 冷知识。

number -> string

1
2
3
4
5
6
7
8
9
// 语法
String(number)
number + ''
'' + number

// 示例
String(1) // '1'
1 + ''    // '1'
'' + 1    // '1'

string -> number

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 语法
Number(string)
parseInt(string) // 除去小数部分,仅保留整数
parseFloat(string)
string - 0

// 示例
Number("1") // 1
Number("1000000000000000000000") // 1e+21 数字多了就成科学记数法
parseInt('1.9') // 1
parseInt('0.1') // 0
parseInt("1000000000000000000000") // 1e+21
parseFloat('1') // 1
parseFloat('1.9') //1.9
'1.9' - 0 // 1.9

x -> boolean

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 语法
Boolean(x)
!!x // !x 的相反值

// 示例
Boolean(1) // true
Boolean(0) // false
Boolean('hi') // true
Boolean(null) // false
Boolean(true) //true
!!1 //true
!!0 //false
!!'hi' //true
!!null //false
!!true //true

x -> string

1
2
3
4
5
6
7
// 语法
String(x)
x.toString()
// 示例
String(true) // 'true'
String(false) //'false'
String(1) //'1'