前端笔记 - JavaScript基础

前端笔记 - JavaScript基础

重新学习前端,基础不牢,地动山摇

对着JavaScript红宝书和ES6的文档一起看与学习。

变量声明 #

主要有三个变量声明关键词:varconstlet

var 可以省略进行定义,但不建议;var有个很关键的特性是声明提升,会讲关键字声明的变量自动提升到函数作用域顶部。

let 和var差不多,但是let声明到范围是块作用域,不会被提升,而var声明到范围是函数作用域。

一个经典的例子就是for循环中的var和let声明

for (var i=0;i<5;i++)
{
    setTimeout(()=>{ console.log(i) },0)
}
// 上述循环运行的结果为 5,5,5,5,5

for (let i=0;i<5;i++)
{
    setTimeout(()=>{ console.log(i) },0)
}
// 上述循环运行的结果为 0,1,2,3,4

const的行为和let基本相同,不过const声明的变量必须声明时初始化,且之后无法再进行修改。

基本类型 #

JavaScript严格来说有7种数据类型,如下:

  • Undefined
  • Null
  • Boolean
  • Number
  • String
  • Symbol
  • Object

通过typeof操作符可以很简单的获取参数的类型。

String #

JS的String对象无法像cpp一样通过代数运算如'b'-'a'直接计算获得某个值的hash index,不过可以通过函数获得

在用JS实现某些算法时String对象的charCodeAt方法很适合用来获取对应的ASCII值,代码如下:

'abc'.charCodeAt(0)   // 97
'abc'.charAt(0)       // "a"

集合引用类型 #

Map #

感觉和cpp std中的map很像,我用JS完成了一下LeetCode的567. 字符串的排列这题,当时没去查如何获取String的ASCII值,就用Map来做了标记,实现了滑动窗口

代码如下:

/**
 * @param {string} s1
 * @param {string} s2
 * @return {boolean}
 */
var checkInclusion = function (s1, s2) {
    let mark = new Map();
    for (i of s1) {
        if (mark.has(i)) {
            mark.set(i, mark.get(i) + 1);
        } else {
            mark.set(i, 1);
        }
    }

    let count = 0;
    for (let i = 0; i < s2.length; i++) {
        if (mark.get(s2[i]) > 0) {
            mark.set(s2[i], mark.get(s2[i]) - 1);
            count++;
            if (count == s1.length) {
                return true;
            }
        } else {
            if (count > 0) {
                for (let j = i - count; j < i && (mark.get(s2[i]) == 0 || mark.get(s2[i]) == undefined); j++) {
                    mark.set(s2[j], mark.get(s2[j]) + 1);
                    count--;
                }
                if (mark.get(s2[i]) > 0) {
                    mark.set(s2[i], mark.get(s2[i]) - 1);
                    count++;
                }
            }
        }
    }
    return false;
};

待补充:2020-02-10