LE (Lexical Environment) - 词法环境
词法环境会根据运行更改 预处理词法环境为window
var a = 1;var b;c = 3;function d() {}var e = function () {};// 预处理词法环境window,LE会随运行变化LE = {a:undefined,b:undefined,// 没有cd,// 对函数的一个引用e: undefined}
优先级
同名情况下,函数声明优先
console.log(f); // chrome:ƒ f() {console.log(2);}; Quokka:[λ: f] at fvar f = 1;function f() {console.log(2);}
同名函数后项覆盖前项
console.log(f); // chrome:ƒ f() {console.log(3);}; Quokka:[λ: f] at fvar f = 1;function f() {console.log(2);}function f() {console.log(3);}
函数中出现形参与内容冲突,变量以传入实参为准,函数声明依然优先
function n(a, b) {console.log(a); // chrome:ƒ a() {}; Quokka:[λ: a] at aconsole.log(b); // chrome:34; Quokka:34 at bvar b = 100;console.log(b); // chrome:100; Quokka:100 at bfunction a() {}}n(12, 34);
作用域
运行时 代码中某些特定部分变量,函数和对象的可访问性 隔离变量,不同作用域同名变量互不干扰 作用域分层,内层作用域可以访问外层作用域变量
var a = 1;function fn() {var a = 3console.log(a); // 3}console.log(a); // 1fn()console.log(a); // 1
作用域链
本层作用域没有往上层作用域查找,全局作用域没有就放弃查找,报错
var x = 10function fn() {console.log(x); // 10}function show(f) {var x = 10;(function () {f()})()}show(fn)
fn函数中取自由变量时从创建fn的作用域中取,无论fn函数在什么地方调用
提升
变量提升
把调用变量的操作放在声明之前
函数提升
函数声明之前调用函数 函数表达式不会提升函数
变量的本质
栈内存 基本数据的值,对象的地址
- const —- 不可修改基本数据的值,对象的地址
-
变量的生命周期
函数外变量
- js加载到变量所在行时产生
- js执行完死亡
函数内变量
浮点数运算存在变数
const a = 0.1 + 0.2; // 0.30000000000000004
浮点数在计算机中总长度64位 最高位 为符号位 接下来11位 是指数位 最后52位是小数位,也就是有效的数字部分 对于一些存在无限循环的小数位浮点数,会截取前52位,从而失去精度
const a = 0.1 + 0.2;加数乘2取整,顺序排列,换算成2进制数0.1->0.000110011...无限循环0.2->0.00110011...无限循环截取52位(失去精度)相加后转换为10十进制
引用数据类型
字符串逆序
function reverseStr1(str) {const result = str.split("");result.reverse();return result.join("");}
function Stark() {this.data = [];this.top = 0;}Stark.prototype = {push(el) {this.data[this.top++] = el;return this.top;},pop() {return this.data[--this.top];},length() {return this.top;},};function reverseStr(str) {const s = new Stark();for (const i of str.split("")) {s.push(i);}const len = s.length();let result = "";for (let i = 0; i < len; i++) {result += s.pop();}return result;}
递归
- 假设递归函数已经写好
- 寻找递推关系
- 将递推关系的结构转换为递归体
- 将临界条件加入递归体
/* 1. 假设递归函数已经写好sum = add1To(100);2. 寻找递推关系add1To(n) = n + add1To(n - 1);4. 将临界条件加入递归体n==1 return 1*/function add1To(n) {if (n == 1) {return 1;}return n + add1To(n - 1);}
/*1. 假设递归函数已经写好sum = oddSum1To(5);2. 寻找递推关系oddSum1To(n) = n + oddSum1To(n-2)4. 将临界条件加入递归体n==1 return 1ps: n % 2 == 1 奇数n % 2 == 0 偶数*/function oddSum1To(n) {if (n % 2 == 0) {n--;}if (n == 1) {return 1;}return n + oddSum1To(n - 2);}
// (第0项)1 1 2 3 5 8 ...function fib(n) {if (n == 0 || n == 1) {return 1;}return fib(n - 1) + fib(n - 2);}
function recursionReverseStr(str) {if (!str) {return "";}return str.slice(-1) + recursionReverseStr(str.slice(0, -1));}
字符串内出现字符和其最大值
function maxStr(str) {if (str === '') {return 'is empty string';}if (typeof str !== "string") {return 'is not string';}let numOfMax = 0;let strOfMax = "";const strMap = {};for (const iterator of str) {if (strMap[iterator]) {strMap[iterator]++;} else {strMap[iterator] = 1;}if (strMap[iterator] > numOfMax) {numOfMax = strMap[iterator];strOfMax = iterator;} else if (strMap[iterator] === numOfMax) {numOfMax = strMap[iterator];strOfMax += iterator;}}if (strOfMax.length > 1) {strOfMax = strOfMax.split("");}return { numOfMax, strOfMax };}
字符串去重
function removeDuplicates(str) {if (str === "") {return "is empty string";}if (typeof str !== "string") {return "is not string";}const newSet = new Set();for (const iterator of str) {newSet.add(iterator);}return [...newSet].join("");}
