概述

计算机是通过操作值(如数值字面量3.14)或文本(如“hello”)来工作的,编程语言中这些可以"表示"和"操作"的值(values)被称为类型(types)。

程序在需要把某个值保存下来以方便将来使用时,会把这个值赋给(或存入)变量(Variable)。

类型Types

  • 原始类型(primitive types):原始值是不可修改的

    • 数值Number
    • 字符串值String
    • 布尔值Boolean
    • null
    • undefined
  • 对象类型(object types)

    • 一个普通的JavaScript对象是一个个命名值(properties属性)组成的无序集合。

值Values

  • 数值Number

    JavaScript的主要数值类型Number用于表示整型和近似实数。JavaScript使用的是IEEE 754标准定义的64位浮点格式表示数值

    • 整数字面量

      0 //默认十进制
      1
      99
      0xff // => 255 十六进制以0x开头
      //ES6后的二进制和八进制表示
      0b10101 // 0b开头
      0o43 // 0o开头
      
    • 浮点字面量

      • [digits].[digits][(E/e)[(+|-)]digits]

        0.314
        .33333
        6.02e23 // => 6.02x10^23
        1.41415415E-32// => 1.41415415x10^(-32)
        
    • 数值字面量分隔符_

      let billion = 1_000_000_000; // _作为千分位分隔符
      let bytes = 0x89_AB_CD_ef // _作字节分隔符
      let bits = 0b0001_1101_1100 // _作半字节分隔符
      let fraction = 0.123_456_789 // 小数中也可用
      
    • 浮点数丢失精度

      let sum1 = .3 - .2;
      let sum2 = .2 - .1;
      console.log(sum1 === sum2); // => false !!
      
    • BigInt

      ES2020为JavaScript定义了一种新的数值类型BigInt。该数值类型的值也是整数,能够表示64位整数,但由于没考虑方式时序攻击而不适合加密。

      字面量:

      1234n // 一个BigInt类型字面量
      0b1101101n //二进制BigInt
      0o7171 //八进制
      0x12354abf //十六进制
      

      构造函数BigInt(Number/String) 用于转换为BigInt类型的值。

  • 文本Text

    JavaScript中表示文本的类型是String,即字符串。字符串时16位(UTF-16)不可修改的有序序列,每一个值都表示一个Unicode字符。

    • 字符串字面量

      "" //空字符串
      'myblog'
      "3.1415926"
      'name = “Zenyet”'
      "Whould't u perfer Zenyet's blog?"
      "with space "
      'inside is "you"'
      //ES5 \ 可以让一行字符串分成若干行
      "one\
       two\
       three"
      
    • 模版字面量Template Literals

      ES6及之后版本中,字符串字面量可以用反引号(``)来定界。

      let name = "Zenyet";
      // get value by ${varName}
      let greeting = `Hello, ${name}`; // => Hello, Zenyet
      

      String.raw()

      `\n`.length // => 1: 字符串中只包含一个换行符
      String.raw`\n`.length // => 2: 一个反斜杠和一个字母n
      
  • 布尔值Boolean

    布尔值表示真或假、开或关、是或否。这个类型只有两个值:true/false.

  • null和undefined

    null是一个语言关键字,求值为一个特殊值,通常用于表示某个值不存在。

    undefined也表示值不存在,但undefined表示一种更深层次的不存在,一般地,未初始化的值就是undefined。

    console.log(undefined == null); // => true
    console.log(undefined === null); // => false
    console.log(typeof undefined); // => undefined
    console.log(typeof null); // => object
    
  • 符号Symbol

    符号是ES6新增的一种原始类型,用作非字符串的属性名。因为js对象是一个属性(properties)的无序集合,每个属性都是name/value对。属性名在ES6之前必须是字符串,在符号出现后可以作为属性名。

    Symbol没有字面量语法。可以使用构造函数Symbol(optional String parameter)获取一个永远不会返回同一个值的值。

    let strname = "string name";
    let symname = Symbol("propname");
    typeof strname; // => String
    typeof symname;// => Symbol
    let obj = {}; // 字面量方式创建一个对象obj
    obj[strname] = 1; //使用字符串名定义一个属性
    obj[symname] = 2; //使用符号名定一个一个属性
    
  • 全局对象

    全局对象的属性(properties)是全局性定义的标识符,可以在JavaScript程序的任何地方使用。JavaScript解析器启动后,都会创建一个新的全局对象并为其添加一组初始的属性:

    • 全局常量:undefined、Infinity和NaN
    • 全局函数:isNaN()、parseInt()、 eval()…
    • 构造函数:Date()、RegExp()、Object()、Array()…
    • 全局对象:Math、JSON…

    Node和浏览器中:

    Node: global属性引用全局对象

    浏览器: window属性引用该全局对象

    ES2020: globalThis

变量声明和赋值Variable Declaration and Assignment

计算机编程中最基本的一个技术就是使用名字(或标识符)表示值。

  • let和const

    let a;
    let b;// 未初始化的值为undefined
    const PI = 3.14; //const修饰的变量必须要初始化
    const KEY = 124; // 建议用大写名字表示
    

    常量不可改变其值。

  • scope作用域

    通过let和const声明的变量和常量具有块作用域,这意味它们只在let和const语句所在的代码块中有定义。通俗来说,{}里面的属于代码块,但形式参数不再{}内也属于代码块内。

  • var声明的变量

    • var声明的变量不再具有作用域。
    • 函数外部使用var,则该变量为全局变量。var和let声明的全局变量的重要区别:通过var声明的全局变量被实现为全局对象的属性(不能使用delete操作符)。
    • var多次声明同名变量合法
    • var声明的最重要特性:作用域提升(hoisting)
      • 在使用var声明变量时,该声明会被提高(或提升)到包含containing function的顶部
  • 解构赋值(destructuring assignment)

    ES6实现了一种复合声明与赋值语法为解构赋值。

    在解构赋值中,等号右边的值是数组或对象(“结构化"的对象),而左边通过模拟数组或对象字面量语法指定一个或多个变量。

    其中左边多余的值被设置为undefined;右边多余的被忽略。

    let [x,y] = [1,2]; // 相当于 let x = 1;let y = 2;
    [x,y] = [x+1,y+1]; // increment
    [x,y] = [y,x]; //exchange
    

    in Array:

    function exchange(x,y){
      return [y,x];
    }
    function square(y,x){
      return [y*y,x*x];
    }
    let [a,b] = exchange(1,2); // => a=2,b=1
    let [y,x] = square(a,b); // => x=4,y=1 
    

    in Object:

    let obj = {x:1,y:2};
    for(const[name,value] of Ojbect.entries(obj)){
      console.log(name,value);
    }