LE (Lexical Environment) - 词法环境

词法环境会根据运行更改 预处理词法环境为window

  1. var a = 1;
  2. var b;
  3. c = 3;
  4. function d() {}
  5. var e = function () {};
  6. // 预处理词法环境window,LE会随运行变化
  7. LE = {
  8. a:undefined,
  9. b:undefined,
  10. // 没有c
  11. d,// 对函数的一个引用
  12. e: undefined
  13. }

优先级

同名情况下,函数声明优先

  1. console.log(f); // chrome:ƒ f() {console.log(2);}; Quokka:[λ: f] at f
  2. var f = 1;
  3. function f() {
  4. console.log(2);
  5. }

同名函数后项覆盖前项

  1. console.log(f); // chrome:ƒ f() {console.log(3);}; Quokka:[λ: f] at f
  2. var f = 1;
  3. function f() {
  4. console.log(2);
  5. }
  6. function f() {
  7. console.log(3);
  8. }

函数中出现形参与内容冲突,变量以传入实参为准,函数声明依然优先

  1. function n(a, b) {
  2. console.log(a); // chrome:ƒ a() {}; Quokka:[λ: a] at a
  3. console.log(b); // chrome:34; Quokka:34 at b
  4. var b = 100;
  5. console.log(b); // chrome:100; Quokka:100 at b
  6. function a() {}
  7. }
  8. n(12, 34);

作用域

运行时 代码中某些特定部分变量,函数和对象的可访问性 隔离变量,不同作用域同名变量互不干扰 作用域分层,内层作用域可以访问外层作用域变量

  1. var a = 1;
  2. function fn() {
  3. var a = 3
  4. console.log(a); // 3
  5. }
  6. console.log(a); // 1
  7. fn()
  8. console.log(a); // 1

作用域链

本层作用域没有往上层作用域查找,全局作用域没有就放弃查找,报错

  1. var x = 10
  2. function fn() {
  3. console.log(x); // 10
  4. }
  5. function show(f) {
  6. var x = 10;
  7. (function () {
  8. f()
  9. })()
  10. }
  11. show(fn)

fn函数中取自由变量时从创建fn的作用域中取,无论fn函数在什么地方调用

提升

变量提升

把调用变量的操作放在声明之前

函数提升

函数声明之前调用函数 函数表达式不会提升函数

变量的本质

栈内存 基本数据的值,对象的地址

  • const —- 不可修改基本数据的值,对象的地址
  • let —- 在{}中使用则会限制作用域在{}

    变量的生命周期

  • 函数外变量

    • js加载到变量所在行时产生
    • js执行完死亡
  • 函数内变量

    • 该变量所在函数被调用时,js加载到变量所在行产生
    • 函数执行结束死亡

      数据类型

      基础数据类型

  • 浮点数运算存在变数

    1. const a = 0.1 + 0.2; // 0.30000000000000004

    浮点数在计算机中总长度64位 最高位 为符号位 接下来11位 是指数位 最后52位是小数位,也就是有效的数字部分 对于一些存在无限循环的小数位浮点数,会截取前52位,从而失去精度

  1. const a = 0.1 + 0.2;
  2. 加数乘2取整,顺序排列,换算成2进制数
  3. 0.1->0.000110011...无限循环
  4. 0.2->0.00110011...无限循环
  5. 截取52位(失去精度)
  6. 相加后转换为10十进制

引用数据类型

字符串逆序

  1. function reverseStr1(str) {
  2. const result = str.split("");
  3. result.reverse();
  4. return result.join("");
  5. }
  1. function Stark() {
  2. this.data = [];
  3. this.top = 0;
  4. }
  5. Stark.prototype = {
  6. push(el) {
  7. this.data[this.top++] = el;
  8. return this.top;
  9. },
  10. pop() {
  11. return this.data[--this.top];
  12. },
  13. length() {
  14. return this.top;
  15. },
  16. };
  17. function reverseStr(str) {
  18. const s = new Stark();
  19. for (const i of str.split("")) {
  20. s.push(i);
  21. }
  22. const len = s.length();
  23. let result = "";
  24. for (let i = 0; i < len; i++) {
  25. result += s.pop();
  26. }
  27. return result;
  28. }

递归

  1. 假设递归函数已经写好
  2. 寻找递推关系
  3. 将递推关系的结构转换为递归体
  4. 将临界条件加入递归体
  1. /* 1. 假设递归函数已经写好
  2. sum = add1To(100);
  3. 2. 寻找递推关系
  4. add1To(n) = n + add1To(n - 1);
  5. 4. 将临界条件加入递归体
  6. n==1 return 1
  7. */
  8. function add1To(n) {
  9. if (n == 1) {
  10. return 1;
  11. }
  12. return n + add1To(n - 1);
  13. }
  1. /*
  2. 1. 假设递归函数已经写好
  3. sum = oddSum1To(5);
  4. 2. 寻找递推关系
  5. oddSum1To(n) = n + oddSum1To(n-2)
  6. 4. 将临界条件加入递归体
  7. n==1 return 1
  8. ps: n % 2 == 1 奇数
  9. n % 2 == 0 偶数
  10. */
  11. function oddSum1To(n) {
  12. if (n % 2 == 0) {
  13. n--;
  14. }
  15. if (n == 1) {
  16. return 1;
  17. }
  18. return n + oddSum1To(n - 2);
  19. }
  1. // (第0项)1 1 2 3 5 8 ...
  2. function fib(n) {
  3. if (n == 0 || n == 1) {
  4. return 1;
  5. }
  6. return fib(n - 1) + fib(n - 2);
  7. }
  1. function recursionReverseStr(str) {
  2. if (!str) {
  3. return "";
  4. }
  5. return str.slice(-1) + recursionReverseStr(str.slice(0, -1));
  6. }

字符串内出现字符和其最大值

  1. function maxStr(str) {
  2. if (str === '') {
  3. return 'is empty string';
  4. }
  5. if (typeof str !== "string") {
  6. return 'is not string';
  7. }
  8. let numOfMax = 0;
  9. let strOfMax = "";
  10. const strMap = {};
  11. for (const iterator of str) {
  12. if (strMap[iterator]) {
  13. strMap[iterator]++;
  14. } else {
  15. strMap[iterator] = 1;
  16. }
  17. if (strMap[iterator] > numOfMax) {
  18. numOfMax = strMap[iterator];
  19. strOfMax = iterator;
  20. } else if (strMap[iterator] === numOfMax) {
  21. numOfMax = strMap[iterator];
  22. strOfMax += iterator;
  23. }
  24. }
  25. if (strOfMax.length > 1) {
  26. strOfMax = strOfMax.split("");
  27. }
  28. return { numOfMax, strOfMax };
  29. }

字符串去重

  1. function removeDuplicates(str) {
  2. if (str === "") {
  3. return "is empty string";
  4. }
  5. if (typeof str !== "string") {
  6. return "is not string";
  7. }
  8. const newSet = new Set();
  9. for (const iterator of str) {
  10. newSet.add(iterator);
  11. }
  12. return [...newSet].join("");
  13. }