【JS基础整理—No.04】作用域

写在前面:执行上下文创建阶段,其中一个过程是,创建作用域,接下来就简单谈谈我对作用域的理解。

目录

一、基本概念

二、词法作用域

三、块级作用域

  🍕 最后整理的面试题


一、基本概念

定义:程序中定义变量的区域,它决定了当前执行代码对变量的访问权限。

产生:代码定义的时候

作用域链:当前作用域没有到上层作用域查找

作用域包括:全局作用域,局部作用域(即,函数作用域,块级作用域) ❗没有对象作用域

//注意和闭包区分👇
function fun(){
    var num=123;
    var a='aa';     
    function fun2(){
        console.log(num);
    }
    fun2();
}
fun(); //输出:123

除此以外,还接触到了词法作用域,块级作用域的概念 👇

二、词法作用域

定义:意味着函数被定义的时候,它的作用域就已经确定了,和拿到哪里执行没有关系,因此词法作用域也被称为 “静态作用域”。

//🍕面试题
var x=10;
function f(){
    console.log(x);
}
function show(f){
    var x=20;
    f()
}
show(f); //10 三个作用域(两个函数作用域并列) 若当前作用域没有到上层作用域查找

过程分析:

三个作用域:全局作用域,f 函数作用域,show 函数作用域

f 里访问了本地作用域中没有的变量 x 。根据前面说的,引擎为了拿到这个变量就要去 f 的上层作用域查询,那么 f 的上层作用域是什么呢?是它 调用时 所在的 show 作用域?还是它 定义时 所在的全局作用域?

这里就需要用词法作用域解释了,函数作用域在定义时被创建,和调用没有关系。

三、块级作用域

定义:任何一对花括号{}中的语句都属于一个块级作用域,{} 中的所有变量在代码块外都是不可见的。

1.块级作用域与变量声明

在ES6之前,我们都是用var来声明变量,而且JS只有函数作用域和全局作用域,没有块级作用域,所以{}限定不了var声明变量的访问范围。ES6新增的let,可以声明块级作用域的变量。

// var定义变量
if(true){
    var x = 0;
}
console.log(x); //0
​
// let定义变量
if(true){
    let x = 0;
}
console.log(x); //报错

var, let 关于块级作用域的场景

//var定义变量
for(var i = 0; i < 3; i++) { 
  setTimeout(function() {  
    console.log(i);       
  }, 0);
}
//结果:3,3,3
 
//let定义变量
for(let i = 0; i < 3; i++) { 
  setTimeout(function() {  
    console.log(i);       
  }, 0);
}
//结果:0,1,2

我们知道函数调用完后,变量会被销毁,我们可以用这个特性来模拟出var的块级作用域

for(var i = 0; i < 3; i++) { 
  (function(i){
    setTimeout(function() {  
        console.log(i);       
    }, 0);
  }) (i)
}
//结果:0,1,2

2.块级作用域与函数声明

除了块级作用域与变量声明的问题,还发现对于函数声明

console.log(a)      //function a(){ return 1}
console.log(b)      //undefined 
function a(){ return 1}
if(true){
    function b(){ return 1}
}

 👉【ES6】关于var, let和const的区别_Chailo的博客-CSDN博客

🍕 最后整理的面试题

//🍕面试题1
var fn = function(){
    console.log(fn);
}
fn(); //function
//🍕面试题2 ❗ ❗ ❗
var obj = {
    fn2:function(){
        console.log(fn2);
    }
}
obj.fn2();  //报错fn2 is not defined 两个作用域 全局和函数(对象作用域错❌)
//🍕面试题3 ❗ ❗ ❗
var obj = {
    fn2:function(){
        console.log(obj.fn2);//=console.log(this.fn2);  this-->obj
    }
}
obj.fn2();  //function

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值