基础了解

  • 在JavaScript中, 指令被称为语句, 并以分号 (;) 结尾, 也就是每一行代码
    • 虽然非必须, 但这是一个良好的编程习惯
  • JavaScript中区分大小写, 且使用的是Unicode字符集

    • let a 与 let A 是两个不同的变量
    • 至于Unicode字符集, 我看完不知道他在说什么

      注释功能

  • 单行注释 //

  • 多行注释 /**/
  • 注意不要嵌套注释

    变量(基本类型和引用类型)声明

    声明的三种关键字

  • var 声明局部变量和全局变量, 可选初始化一个值, 下面有对 var 和 let 的差异进行讨论

  • let 声明一个块级作用域的局部变量, 可选初始化一个值, 正是因为var定义的都是全局变量的巨大隐患而且为了其他版本的兼容, 才搞了个新关键字 let
  • const 声明一个块级作用域的只读量(或者说常量), 并非全局作用域哦

    变量是什么?

  • 在JavaScript中, 变量就是值的符号名, 可以看成房子的名字

  • 变量也被叫做标识符
  • 事实上, 只要是Unicode字符集里面的字符基本都可以拿来当标识名, 但不合法, 比如 let 好的 = “good”
  • 变量标准的命名规则应该是以字母、下划线 (_) 或者美元符号 ($) 开头; 后续的字符也可以是数字, 比如name, _name, $name

    声明变量的形式

  • var x = 25

  • x = 25 严格模式下, 会报错, 不推荐这么写
  • let x = 25

    var 和 let 声明变量的区别

  • let存在暂时性死区, 因此使用 let 声明的变量不存在变量提升, 且其变量也不能重复声明

  • 应该这样理解: let 存在变量提升, 但 let 也具有暂时性死区, 这使得该变量调用不能发生在声明之前, 所以let表现出来的结果便是不存在变量提升
  • 而使用 var 声明的变量没有这样的考虑
  • 所谓暂时性死区, 便是在变量声明这一行之前, 调用到该变量便会报错, 而变量提升便是调用不报错, 从这个角度看, 暂时性死区与不存在变量提升是一个意思

    变量的初始化

  • 使用 var 和 let 声明变量不赋值的话, 会被分配一个 undefined 的值, 其意为未定义的

  • 如果使用一个未声明的变量的话, 系统会报引用类型的错误, 注意不要和前面的暂时性死区概念混淆
  • 同样的, 当我们想知道一个变量是否被赋值, 我们可以通过该变量是否等于 undefined 来判断

    变量的作用域

  • 这可能就是 let 和 var 最大的区别 —— 作用域的划分界限

  • 在JavaScript中, 变量的定义域一开始并不是以代码块划分界限的, 而是以函数划分的, 如果一个变量在函数内被定义, 函数之外的地方便是不可见的, 也就是说 if 和 for 这种代码块中定义的变量并不是作为局部变量来看待的 ```javascript // Es6 之前, 没有 let 关键字的时候

if(true) { x = 5 // 内部默认为 var x = 5 }

for(i = 0; i<1 ; i++) { y = 5 }

function f1() { z = 5 }

f1() console.log(‘x=’, x, ‘, y=’, y, ‘, z=’, z) // x=5, y=5, z is nodefined

  1. - Es6标准后, let 的出现使得之前的划分形式有了改变. let 以代码块作为作用域划分界限, 与之前的 var 有了根本性的区别, let也使得程序员在理清 if 或是 for 这种代码块时更好理解(其中可能也有后端转型过来易理解的考量)
  2. ```javascript
  3. // Es6之后, 有 let 关键字
  4. if(true) {
  5. let x = 5
  6. }
  7. for(i = 0; i<1 ; i++) {
  8. let y = 5
  9. }
  10. function f1() {
  11. let z = 5
  12. }
  13. f1()
  14. console.log('x=', x, ', y=', y, ', z=', z) // x, y, z are nodefined

变量提升

  • 通俗来说, 就是先上车后补票
  • 在使用 var 声明变量的时候, 你可以先把该变量拿去操作, 也就是操作在声明之前 ```javascript x = 3 console.log(‘x=’, x) // x=3

var x

  1. - JavaScript中, 使用 var 定义的变量会先被提升到该作用域顶部, 用上面来举例那就是4->1->2
  2. - **使用 let 关键字也具有变量提升的效果, 但结果不同, let 声明的变量同样会被提升到作用域顶部, 但该变量具有暂时性死区, 即在该变量声明那一行之前, 对其相关调用都会抛出引用错误**
  3. - 变量提升虽然方便, 但容易让阅读者逻辑混乱, 我们更强调逻辑的连贯性
  4. - 变量提升只是单纯把声明提升到作用域顶部, 并不提供在提升的同时赋值的功能
  5. ```javascript
  6. console.log(x) // x is undefined
  7. var x = 5

函数提升

  • 对于函数来说, 只有函数声明会被提升到顶部, 而函数表达式不会, 如下 ```javascript // 函数声明形式

foo() // 正常执行

function foo() { alert(‘1. Good!’) }

// 函数表达式形式

baz() // 报错, baz is not defined

var baz = function () { alert(‘2. Good!’) }

  1. - 分析: ~~就像变量提升最后说的, 并不提供提升的同时赋值的行为, 所以此时的baz应该是undefined~~, 事实却是baz is not defined (未定义), 那应该是内部对函数表达式有另外的处理, 因此要和变量提升分开考虑
  2. <a name="bv18K"></a>
  3. ## 全局变量
  4. - 即为全局对象的属性, 而全局对象可以通过globalThis获取
  5. - 在默认网页中, 全局对象为 window, 可以使用 window.variable 的语法来设置和访问该变量
  6. - node中, 全局对象则是 global
  7. - 不使用关键字声明的变量也被视为全局变量
  8. ```javascript
  9. (function (){
  10. x = 5;
  11. console.log('1. x=', x); // x=5
  12. })()
  13. console.log('2. x=', x); // x=5, 使用 var, let的话, 这里会报错

常量(Constants)

  • 使用关键字 const 创建的一个只读量, 命名规则与变量相同: 必须以字母/下划线 (_) /美元符号 ($) 开头并可以包含有字母/数字/下划线, 注意常量名不能与变量名/函数名相同
  • 常量在声明时一定要进行初始化, 且在该值作用域中不可更改
  • 常量的作用域划分界限与 let 定义的变量相同, 都是以代码块为界限
  • 当将引用类型赋值给常量时, 其内部变化是不收保护的, 就是说可以改变的

    1. const My_OBJ = {name : 'JavaScript'}
    2. My_OBJ.name = 'Good' // 并不会报错
  • 如果真要将引用类型赋值给常量的话, 要使用Object.freeze()方法冻结对象, 或是启用严格模式 ```javascript const obj = { prop: 42 };

Object.freeze(obj);

obj.prop = 33; // 报错

  1. <a name="Ol6BO"></a>
  2. # 数据结构和类型
  3. <a name="mFTA4"></a>
  4. ## 数据类型
  5. - 基本数据类型: null(空型), undefined(未定义型), boolean(布尔型), int(整型), string(字符串型), symbol(符号型)
  6. - 引用数据类型: array(数组), function(函数), object(对象)
  7. <a name="BNQQM"></a>
  8. ## 数据类型的转换
  9. - **JavaScript是一种弱类型语言, 或者说动态类型语言, 也就是不拘于类型, 不必指定类型, 变量的值不受类型的约束**
  10. - 这里提一下, 我们老师也说JavaScript应该是泛型编程语言, 不会拘束于面向对象, 还是面向过程, 解决问题才是关键
  11. ```javascript
  12. var x = 25
  13. x = 'Good Good study'
  14. x = false
  15. x = 1.252
  16. x = {name: 'ming', age: 18}
  • 注意: 加号 (+) 在其中的作用, 在数值环境时, +做为加法运算使用, 而在字符串环境时, +作为字符串拼接符号使用, 当两种情况均存在时, 以字符串拼接为准, 数值会变成字符串形式 ```javascript x = 25 y = 10 z = ‘good good ‘ w = ‘study’ console.log(x+y) // 35 console.log(z+w) // ‘good good study’ console.log(x+z) // 25good good
  1. - 这里说一下字符串转换为数值的方法, parseInt()[丢失小数部分, 返回整数, 默认十进制]和parseFloat(), 截取值为从头开始的数值部分
  2. ```javascript
  3. str01 = '123abc123'
  4. str02 = 'abc123abc'
  5. str03 = '1.20551'
  6. console.log(parseInt(str01)) // 123
  7. console.log(parseInt(str02)) // NaN
  8. console.log(parseInt(str03)) // 1
  9. console.log(parseFloat(str03)) // 1.20551

undefined 在各环境下, 内部进行的处理

  • 在布尔环境中, undefined 会被视为 false, 也就是说 !undefinedNum == true
  • 在数值环境中, undefined 则会被视为 NaN(not a number)

    undefined 和 null 的区别

  • null 表示没有对象, 该处不应该有值, 或者说终点的意思, 没有了, 结束了

    • null 表示这个房子不能住人了
  • undefined 表示缺少值, 该处有值, 但未定义, 还没结束, 但也还没有开始
    • undefined表示这个房子还没住人
  • 在两者概念方面, 我也懵逼, 希望有好心人帮忙😁
  • null 在数值环境和布尔环境中默认看做为0, 所以 !nullValue == true (true), nullValue+2 == 2 (true)
  • 注意 nullValue == undefined (true), nullValue === undefined (false), 两者都是独立基本类型

    字面量(Literals)

    基础意思

  • 在JavaScript中, 字面量是常量, 其值固定, 而且在脚本中不可更改, 比如false, 3.1415 — MDN

  • 看了一些资料, 描述的跟鬼一样, 在我看来应该是表达方式的意思吧, 像数组的字面量就是数组, 那数组是怎么表示的呢, 就是 [1, 2, 3] 这样的; 像布尔字面量true和false; 像是字符串字面量就是用单引号/双引号括起来的句子, 比如”good”/‘nice’这样的
  • 类型的表现形式, 我是这么理解的

    数组字面量/数组

    1. var arr = ['firefox', 'google', 'edge']
  • 数组元素可以是任一类型, 注意的是数组本身就是一种类, length就是数组实例的属性

  • 注意数组中的逗号问题, 当元素1与元素2之间存在多余的逗号时, 该内存空间会被创建, 值为undefined ```javascript var arr01 = [‘good’, , , ‘study’] var arr02 = [‘good’, ‘study’, ,]

console.log(arr01.length) // 3 console.log(arr01[1]) // undefined console.log(arr02.length) // 2, 逗号在末尾时会被省略

  1. - **显式地将缺失的元素声明为undefined, 将大大提高你的代码的清晰度和可维护性** -- MDN, 我未理解
  2. <a name="mBO73"></a>
  3. ## 布尔字面量/布尔值
  4. - 布尔类型具有两种字面量 false/true
  5. - 不要混淆布尔对象的真与假和布尔类型的原始值 false/true, 布尔对象是对布尔类型的一个包装器 -- MDN, ???
  6. <a name="WOZMf"></a>
  7. ## 整数字面量/整数
  8. - 整数字面量就是整数. 整数可以用十进制, 八进制, 十六进制, 二进制表示
  9. - 十进制: 1, 2, 3
  10. - 八进制: 015, 07, 01(严格模式下, 必须以0o/0O开头)
  11. - 十六进制: 0x15, 0xFF, 0X1
  12. - 二进制: 0b101, 0b100, 0B001
  13. <a name="lnPVk"></a>
  14. ## 浮点数字面量/浮点数
  15. - 组成部分为:
  16. - 十进制整数
  17. - 小数点
  18. - 小数部分(也是十进制数)
  19. - 指数部分(e±十进制数)
  20. - 3.141, 2.14e+10, 1.24e-2
  21. <a name="FyiwE"></a>
  22. ## 对象字面量/对象
  23. - 对象字面量就是在一对花括号内的零个或多个键值对的列表, 如下
  24. ```javascript
  25. let obj = {
  26. name: 'ming',
  27. age: 18,
  28. sex: 'nan',
  29. dept: 'game'
  30. }
  • 我们不能在一行的开头就使用花括号, 这样左花括号会被识别为是一个代码块的起始
  • 对象中的键名可以是Unicode字符集的任意组合, 注意键名不合法的话, 调用时必须使用object[“键名”]的形式, 而不能使用object.key的形式

    1. let obj = {
    2. "game": 'ming', // obj["game"]
    3. 年龄: 18, // obj["年龄"]
    4. _sex: 'nan', // obj["_sex"]
    5. 4: 'game', // obj[4]/obj["4"], 因为对象不使用下标记录, 所以直接使用也没事
    6. "": 'good good study', // obj[""]
    7. "!": 'day day up' // obj.["!"]
    8. }
  • ES6增强的对象字面量内容

    • 创建时设置原型 — ???
    • 简写foo: foo形式的属性赋值
    • 方法定义
    • 支持父方法调用
    • 使用表达式动态计算键名
      1. let obj = {
      2. __proto__: theProtoObj, // 1.
      3. handler, // 2.
      4. toString() { // 3.
      5. return "d" + super.toString() // 4.
      6. },
      7. ['prop_'+(() => 42)()]: 42 // 5.
      8. }

      RegExp字面量

  • 使用两条正斜杠括起来的内容就是

    1. var reg = /123456/

    字符串字面量

  • 用单引号/双引号括起来的零个或多个字符

  • 可以在字符串字面量上使用字符串对象的所有方法 — JavaScript内部会将字符串字面量转化为临时字符串对象, 调用完方法后, 该临时对象就会被废弃

    1. console.log("John's cat".length) // 10
  • ES6中, 新增了一种模板字符串, 通过使用反引号``来表示, 不仅可以跨越行数, 也可以进行插值, 保证代码阅读的连贯性 ```javascript let name = ‘John’

let str = ${name} is cat, to be or not to be ```

  • 字符串中可以使用的一些特殊字符(转义字符) — MDN | \0 | Null字节 | | —- | —- | | \b | 退格符 | | \f | 换页符 | | \n | 换行符 | | \r | 回车符 | | \t | Tab (制表符) | | \v | 垂直制表符 | | \‘ | 单引号 | | \“ | 双引号 | | \\ | 反斜杠字符(\) | | \XXX | 由从0到377最多三位八进制数XXX表示的 Latin-1 字符。例如,\251是版权符号的八进制序列。 | | \xXX | 由从00和FF的两位十六进制数字XX表示的Latin-1字符。例如,\ xA9是版权符号的十六进制序列。 | | \uXXXX | 由四位十六进制数字XXXX表示的Unicode字符。例如,\ u00A9是版权符号的Unicode序列。见Unicode escape sequences (Unicode 转义字符). | | \u{XXXXX} | Unicode代码点 (code point) 转义字符。例如,\u{2F804} 相当于Unicode转义字符 \uD87E\uDC04的简写。 |