共计 2305 个字符,预计需要花费 6 分钟才能阅读完成。
1. 作用域概述
通常来说,一段程序代码中所用到的名字并不总是无效和可用的,而限定这个 名字(变量)的可用性的代码范畴就是这个名字的作用域,作用域的应用进步了程序逻辑的局部性,加强了程序的可靠性,缩小了名字抵触
1.1.js 作用域(es6 之前)分为:全局作用域 部分作用域
1.2. 全局作用域:整个 script 标签 或者是一个独自的 js 文件
var num = 10 ;(这一个标签是写在全局作用域外面 这个变量名是可用的 称之为全局作用域)
1.3. 部分作用域(函数作用域):在函数外部就是部分作用域,这个代码的名字只在函数外部起成果和作用
var num = 10 // 部分作用域
function fn(){
// 部分作用域
var num = 20 ; // 部分下的 num 和全局下的 num 是不抵触的因为输入的不一样
console.log(num) //20
}
fn() // 切记调用
console.log(num) // 10
2. 变量作用域
在 js 中,依据作用域的不同,变量能够分为俩种:全局变量,局部变量
2.1. 全局变量:在全局作用域下的变量 在全局下都能够应用(在函数内部定义的变量)(3. 非凡状况留神一下:如果在函数外部,没有申明间接赋值的变量也属于全局变量)
var num=10;
console.log(num);// 能够打印 10
function fn(){ // 函数
console.log(num)// 也是能够打印的 10
}
fn()
console.log(aru) //4.aru is not defined 不能应用
2.2. 局部变量:在部分作用域下的变量 或者能够了解为在函数外部的变量就是局部变量(在函数外部定义的变量)(留神:函数的形参也能够看做是局部变量 4.aru 是一个形参)
function fun(aru){
var num = 10; //1.num 就是局部变量 特点就是只能在函数外部应用
num = 20; //3 . 如果在函数外部,没有申明(不实用 var)间接赋值的变量也属于全局变量
}
fun();
console.log(num); //2.num is not defined 报错 所以说内部是不能应用的
console.log(num); //3. 20 如果在函数外部,没有申明间接赋值的变量也属于全局变量
2.3. 区别:从执行效率来看全局变量和局部变量
(1)全局变量在任何一个中央都能够应用,只有浏览器敞开的时候才会销毁,比拟占内存资源
(2)局部变量 当咱们程序执行结束就会销毁,比拟节约内存资源
3. 作用域链
3.1. 只有是代码,就至多有一个作用域
var num = 10; // 全局作用域
3.2. 在函数外部的叫做部分作用域
var num = 10;
function fun(){ // 内部函数
var num = 20;
function fn(){//3.3. 在 fun 函数外面有生成了一个 fn 函数 作用域外面诞生了一个新的作用域 外部函数
console.log(num);//3.4. 执行是 20 还是 10 呢 20 用链式查找决定 它会往上一级找有没有 num 一层一层的找就是链式查找
}
fn()}
fun()
3.3. 如果函数中还有函数,那么在这个作用域中就有能够诞生一个作用域
3.4. 依据在外部函数能够拜访内部函数变量的这种机制,用链式查找决定哪些数据能被外部函数拜访,就称为作用域链 (简略了解就是就近准则,谁离的近就执行谁)
案例 1:
function f1(){ //1 能够称为 0 级链
var num = 123; //2 能够称为 1 级链
function f2(){ //2 能够称为 1 级链
console.log(num); //3 能够称为 2 级链 123
}
f2()}
var num = 456; //1 能够称为 0 级链
f1();
案例 2:
var a = 1;
function fn1(){
var a = 2;
var b = '22';
fn2();
function fn2(){
var a = 3;
fn3();
function fn3(){
var a = 4;
console.log(a); //4
console.log(b); //22
}
}
}
fn1();
二、预解析
.1 问
console.log(num) //num is not defined
.2 问
console.log(num) //undefined 坑 1
var num = 10;
~ // 相当于执行了以下代码
var num;
console.log(num); // 只申明不赋值 所以输入就是 undefined
num = 10;
.3 问(间接函数申明 利用关键字来进行申明)
function fn(){console.log(11) //11
}
fn();
.4 问(函数表达式采纳了表达式赋值模式 这里应用 function 赋值的没方法进行函数晋升)
//fun() // 如果放到下面调用呢 undefined 坑 2
var fun = function(){console.log(22) //22
}
fun()
~// 相当于执行了以下代码
var fun; // 只申明不赋
fun(); // 没有这个函数调用必定会报错 所以正确写法是将 fun 写到前面
fun = function(){ // 函数表达式
console.log(22) //22
}
fun();
1. 什么是预解析
js 代码是由浏览器中的 js 解析器来执行的,js 解析器在运行 js 代码的时候分为俩步:预解析和代码执行
1.1. 预解析:js 引擎会把 js 外面所有的 var 还有 function 晋升到以后作用域的最后面
1.2. 代码执行:依照代码的书写程序从上往下执行
2. 预解析分为 变量预解析(变量晋升)和 函数预解析(函数晋升)
2.1. 变量晋升 就是把所有的变量申明晋升到以后的作用域最后面 不晋升赋值操作
2.1. 函数晋升 就是把所有的函数申明晋升到以后作用域的最后面 不调用函数(函数表达式 调用必须写在函数表达式上面)
正文完
发表至: javascript
2021-05-01