JS基础 | 青训营笔记

23 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第4天

JS基础语法

  • 注释:// OR /**/

  • 变量声明:

    • var x = 1;(不用var会自动变为全局变量,可在首行加上'use strict';强制检查var

    • (ES6)let x = 1;推荐。这种声明只在当前作用域中产生效果

    • 新增可命名符号:$,可用作开头

  • (ES6)解构赋值: var [x,y,z] = [1,2,3];快速交换值:;[x, y] = [y, x]

    • 赋值为数组要多加一层嵌套
    • 对于从字典取值还有一些花里胡哨的用法
  • (ES6)常量声明: const PI = 3.14;

  • 运算符:

    • 与/或/非:&& / || / !

    • 三元操作符:条件? 表达式1 : 表达式2

    • 相等:===(比较内存地址,==比较值)

      • 注意:NaN===NaN返回的是false,返回true要用isNaN(NaN);
  • 判断:if (真假) {语句} else if{语句} else {语句},只有一条语句可省略{}

    • 多重判断:switch(参数){case 值: 表达式1; case 值: 表达式2; ... default: 表达式}
    • 视为false的值: null、undefined、0、NaN、'',其余均为true
  • 循环:while(){} 或 do{}while() ; 或 for(;;){},同C

    • for-in:for(var i in 数组/对象){}:对于对于对象i是键,数组i是索引(其实也是键,只不过被当成了索引)(最好别用)
    • (ES6) for-of:修复了数组将索引当键的问题
    • (ES6) 迭代类型.forEach(function([ele, index, obj]){}):ele表元素/值,index表索引/键,obj表迭代类型本身。这些参数都是可选的,但至少要有一个 (推荐这种方法)
  • 操作符:|| && !

基础数据类型

  • 数字:不区分整型和浮点数

    • 特殊表示:NaN(无法计算时的结果)、Infinity(无限大)
  • 布尔:true/false

  • 自定义对象:{} ,通过var声明,键名可不用''包含(有特殊字符除外),值可为一个函数,相当于python的字典和无法实例化的类?

    • 获取/修改值:对象名.键名 or 对象名['键名'](尽量用后一种,有特殊字符必须用后一种)
    • 删除属性:delete 对象名['键名'](对方法不起作用
    • 判断是否拥有键: .hasOwnProperty('键名');(不要用xx in xx,这种判断时也会包括继承的属性如toString)
  • 字符串: 支持下标索引,多行字符串用``(反引号)表示

    • 格式化(ES6) ${字符串变量},如你好, ${name}, 你今年${age}岁了! (用反引号) ,类似python的f'{}'

    • 常用操作:

      • s.length/toUpperCase()/toLowerCase():返回长度、字符全大写/小写

      • .strim():同python的strip()

      • s.split(符号/正则):同python的split()

      • s.replace(s1/正则,s2/函数名):返回将子串s1替换为s2后的字符串,只替换一次

        • 全局替换需要用正则表达式: s.replace(/s1/g,s2)(s1不需要引号)
        • 可以在s2中用“”符引用正则中的分组,如1
      • s.indexOf(字符/字符串):搜索字符位置返回索引,失败返回-1

      • s.charAt(索引):返回索引指向的字符

      • s.substring/slice(索引1,索引2):返回索引区间子串,左闭右开

  • 其他:undefinednull(可以通过将变量值设为 null 清空变量)

  • ES6对象:

    • Map: let m = new Map([二维数组]),有以下方法:

      • m.set(键, 值):增添键值对
      • m.has(键):判断键是否存在
      • m.get(键):获取值
      • m.delete(键):删除键值对
    • Set: let s = new Set([一维数组]),不允许有重复元素,方法:

      • s.add/delete(元素)
    • tips:

      • 获取时间: let now = new Date();now.getxx()方法 ,月份从0开始

函数

  • 定义:

    • function 函数名(参数1, 参数2){语句},参数可为函数

    • (ES6) function 函数名(参数1, 参数2,...rest){语句}:

      • ...rest: 表示将多传的参数赋给rest关键字,其为一个数组,相当于python中的*params
    • (ES6)箭头函数let 函数名 = (参数) => {语句} 等价于function (参数){语句}

      • 箭头函数中没有自己的 this 指向,所有的 this 指向都指向它的上一层 this
      • function中的this指向它的调用对象
      • 箭头函数没有arguments关键字
    • 匿名函数: function (参数){语句}; or (参数) => {语句}

      • 直接使用匿名函数:(匿名函数)();
  • 作用域:

    • 全局:非函数内定义的变量/函数影响全局,可通过全局对象window.变量名/函数调用,要改变某个函数用window.函数名。只有一个
    • 局部:函数内的作用域
    • 块级:循环/条件判断等代码块内的作用域
    • 作用域链:使用本作用域内没有定义的变量时,将会去外层作用域寻找,直到找到
  • 闭包: 利用作用域链可以写出嵌套函数

    • 作用:

      1. 让内层函数使用外层函数的变量
      2. 让外层函数变量能保留在内存中
    • 优缺点:

      1. 有利于封装,可以访问函数中的局部变量
      2. 内存浪费严重,可能产生内存泄漏
  • (ES6)生成器:function* 函数名(参数){} 每次调用next()时才执行(或使用for循环),遇到yield则返回值,类似python的生成器

  • 其他:

    • arguments关键字:指向函数传入的所有参数,为一个类数组,可以用.length等方法,常用于判断传入参数的个数(也可用 ...rest解决),只在函数内部使用

      • 函数传入参数个数:函数名.length
    • 重构保留函数:window.函数名 = function(){}

    • this关键字:始终指向调用函数的对象,无对象则指向全局,只在函数内部或参数中使用

      • 将this指向指定对象:

        • 函数名.call(对象名,参数1,参数2)

          • 无调用对象的函数通常绑定到null上
        • 函数名.apply(对象名,[参数1,参数2])

          • []可以是数组/类数组
        • 函数名.bind(对象名,参数1,参数2)()