笔记首发
一、作用域
- 😴我们学变量,
不是
在任何地方都可以使用- 😴变量有一个
使用区间
, 这个可以使用的区间就叫做作用域
1、全局作用域
- 😫
script标签内部
声明的变量,就是全局作用域的变量- 😏在全局作用域声明的变量, 在
哪里
都可以使用- 😣浏览器在运行的时候,会给我们一个
window对象
, 我们的全局作用域内声明的变量,全都在window对象中
2、局部(函数)作用域
- 🤒 在函数内部的大括号内,这个区间叫做
函数作用域
- 😴 在函数作用
内声明的变量
, 只能在当前函数内部使用
, 在函数外部(超过作用域了) 就无法使用- 😪 函数作用域内声明的变量, 不会挂载到
window对象
上
// 在全局作用域中声明的变量, 同时他也会挂载到全局对象window
var a = 100;
// 在全局作用域中声明的变量, 同时他也会挂载到全局对象 window
var a1 = '这是我手写的';
console.log(window)
function fn() {
// 这里边就是函数作用域
var amyFn = '我是在函数作用域内声明的变量';
// 我是在函数作用域内声明的变量
console.log(amyFn)
}
fn()
// amyFn is not a defined
console.log(amyFn); //报错
二、作用域链
1、变量的访问规则
- 😴 会先在自己
当前作用域内
查找, 找到直接使用(打印)- 😴 如果没有找到,会向
上层作用域查
找, 不会向下层查找- 😴 如果上层作用域内也没有找到, 会继续向
上层作用域的上层作用域
查找(相当于是去自己爷爷级作用域)- 😴 一直会找到最顶层的
全局作用域
, 找到就是用,找不到
就报错
var a = 100;
function fn() {
/**
* 会先在自己当前作用域(fn函数内部)查找, 找到直接使用, 这里找不到, 因为函数内部没有声明变量a
* 那么会去自己的上一层作用域(全局作用域)中查找, 找到直接使用
*/
console.log(a) // 100
function fn1() {
var a = 200;
console.log(a); //200
}
fn1()
}
fn()
var a = 1;
function fn() {
function fn1() {;
console.log(a) // 1
/**
* 查找规则:
* 1. 在当前作用域(fn1函数内部)查找, 找到直接使用, 但是没找到, 所以会去父级(fn函数内部)
* 2. 在父级作用域(fn函数内部)查找, 找到直接使用, 但是没找到, 所以会去父级(全局)
* 3. 在全局作用域查找, 找到直接使用, 找到了var a = 1; 所以会打印1
*/
}
fn1()
}
fn()
function fn() {
function fn1() {
console.log(a)
/**
* 查找规则:
* 1. 在当前作用域(fn1函数内部)查找, 找到直接使用, 但是没找到, 所以会去父级(fn函数内部)
* 2. 在父级作用域(fn函数内部)查找, 找到直接使用, 但是没找到, 所以会去父级(全局)
* 3. 在全局作用域查找, 找到直接使用, 没找到 所以会报错
*/
}
fn1()
}
fn()
2、变量的赋值规则
- 🤒 会先在自己
当前作用域
内查找, 找到直接赋值- 🤒 如果没找到, 会向
上层作用域
查找, 不会向下层查找- 🤒 如果上层作用域内也没有找到, 会继续
向上层作用域的上层作用域
查找(去自己的爷爷级作用域)- 🤒 一直会找到最顶层的
全局作用域
,找到
直接赋值
,找不到
将变量定义为全局变量
,并赋值
function fn() {
function fn1() {
a = 1
/**
* 赋值规则:
* 1. 在当前作用域(fn1函数内部)查找, 找到直接赋值, 但是没找到, 所以会去父级(fn函数内部)
* 2. 在父级作用域(fn函数内部)查找, 找到直接使用, 但是没找到, 所以会去父级(全局)
* 3. 在全局作用域查找, 找到直接赋值, 没找到; 所以会将变量定义为全局变量并赋值
*/
}
fn1()
}
fn()
console.log(a) // 1
3、作用域链(纯概念)
- 😦 在自己作用域内查找, 找不到去上层, 不会去下层, 这样一层一层的一个链条 我们叫做
作用域链
- 😑 简单总结:
永远向上查找, 不会向下
三、递归函数
1、递归函数
- 😫 条件1:一个函数在内部调用了
自身
- 😇 条件2:在合适的实际,结束调用(结束递归),一定要有, 不然就是
死递归
function fn(n) {
if (n == 1) {
return 1
}
// return 4 的阶乘
// return 4 * 3 的阶乘
// return 4 * fn(3)
return n * fn(n - 1)
}
var sum = fn(4)
console.log(sum) // sum就是4的阶乘 24
2、课堂案例
/**
* 现在有一个特殊的数列,前两位的值是固定为1
* 从第三位开始, 他的值为前两位相加的和
*
* 1 1 2 3 5 8 13 21 34 55
* 递归比较好用, 但是计算量大的时候慎用
*/
function fn(n) {
if (n == 1 || n == 2) {
return 1;
}
/**
* 假设 我想求 第六位
*
* return 第五位 + 第四位
* return fn(5) + fn(4)
* return fn(n - 1) + fn(n - 2)
*/
return fn(n - 1) + fn(n - 2);
}
var sum = fn(200);
console.log(sum);