1、迭代思想 vs 递归思想
1、
- 递归 当函数调用自身时
- 迭代 正常一步一步来
2、举例说明
- 这是实现乘方思想
pow(2, 2) = 4
pow(2, 3) = 8
pow(2, 4) = 16
1、迭代思想
//迭代
function pow(x, n) {
let result = 1;
for (var i = 0; i < n; i++) {
result *= x;
}
return result;
}
console.log(pow(2, 3)); // 8
2、递归思想
function pow(x, n) {
if (n == 1) return x;
return x * pow(x, n - 1);
}
console.log(pow(2, 3)); // 8
当pow(x, n)被调用时,执行分为两个分支:
if n==1 = x
/
pow(x, n) =
\
else = x * pow(x, n - 1)
3、进一步简化一下
function pow(x, n) {
return n == 1 ? x : x * pow(x, n - 1);
}
console.log(pow(2, 3)); // 8 注意 函数结构需要 return 出去
- 注意 递归有层数限制, 深层多次递归会影响 性能
2、执行上下文和堆栈
1、 所有函数的过程都是相同的:
- 当前上下文在堆栈顶部“记住”。
- 为子调用创建新上下文。
- 当子调用完成时——从堆栈中弹出前一个上下文,并继续执行
2、举例说明 常用且重要的部分 递归遍历
如果想把 number 加起来 怎么处理? 多个层级的 问题
let company = {
sales: [
{
name: "skt",
sum: 120,
},
{
name: "dk",
number: 100,
},
],
development: {
frontend: [
{
name: "dev1",
number: 200,
},
{
name: "dev2",
number: 190,
},
],
backend: [
{
name: "jiwan",
number: 130,
},
],
},
};
- 使用递归遍历
function sum1(dep) {
if (Array.isArray(dep)) {
return dep.reduce((prev, cur) => prev + cur.number, 0);
} else {
let sum = 0;
for (let item of Object.values(dep)) {
sum += sum1(item);
}
return sum;
}
}
alert(sum1(company)); // 740
- 非常nice
3、let的块级 作用域
1、 其实 函数本身有作用域
- 在两块内 可以work
{
// show message
let message = "Hello";
alert(message);
}
{
// show another message
let message = "Goodbye";
alert(message);
}
- 放一起
// show message
let message = "Hello";
alert(message);
// show another message
let message = "Goodbye"; // Error: variable already declared
alert(message);
2、for while if 也有块级
if (true) {
let phrase = "Hello!";
alert(phrase); // Hello!
}
alert(phrase); // Error, no such variable!
3、经典 函数嵌套
- 内层 返回一个函数
function makeCounter() {
let count = 0;
return function() {
return count++;
};
}
let counter = makeCounter();
alert( counter() ); // 0
alert( counter() ); // 1
alert( counter() ); // 2
4、最简单函数过程
5、函数名称 name
- 下面都可 打印出 name
常规声明 + 函数表达式
function sayHi() {
alert("Hi");
}
alert(sayHi.name); // sayHi
let sayHi = function() {
alert("Hi");
};
alert(sayHi.name); // sayHi (there's a name!)
- 下面 这个也可
function f(sayHi = function() {}) {
alert(sayHi.name); // sayHi (works!)
}
f();
let user = {
sayHi() {
// ...
},
sayBye: function() {
// ...
}
}
alert(user.sayHi.name); // sayHi
alert(user.sayBye.name); // sayBye
// function created inside array
let arr = [function() {}];
alert( arr[0].name ); // <empty string>
6、函数长度 length 表示函数参数的长度
- ...more 并未 算在 length内
function f1(a) {}
function f2(a, b) {}
function many(a, b, ...more) {}
alert(f1.length); // 1
alert(f2.length); // 2
alert(many.length); // 2
7、基本的垃圾收集
function f() {
let value = 123;
return function() {
alert(value);
}
}
let g = f(); // while g function exists, the value stays in memory
g = null; // ...and now the memory is cleaned up
6、几个题目
let name = "John";
function sayHi() {
alert("Hi, " + name);
}
name = "Pete";
sayHi(); // what will it show: "John" or "Pete"? // Pete
function makeWorker() {
let name = "Pete";
return function() {
alert(name);
};
}
let name = "John";
// create a function
let work = makeWorker();
// call it
work(); // what will it show? Pete 块级
7、call/apply/bind ?
func.call(context, ...args);
func.apply(context, args); // args是个数组
- 延迟 ms 后 执行
// 延迟 xx ms 后执行 函数
function delay(fn, ms) {
return function (...args) {
setTimeout(() => {
fn.apply(this, arguments);
}, ms);
};
}
//test
let fn1000 = delay(alert, 1000);
fn1000("test");