鸿蒙-JS-第三周day01

一、作用域:

1.变量的作用域

作用域是变量的可作用范围,变量只有在自己的作用域下才会生效。

函数会产生作用域,在函数内定义的变量只能在函数内使用。

1.2 作用域分类

局部作用域: 函数内定义的变量和形参的作用域就是局部作用域;这样的变量称之为局部变量

全局作用域: 在函数外面定义的变量的作用域是全局作用域;这样的变量称之为全局变量

块级作用域: 在代码块中定义的变量的作用域是块级作用域;这样的变量称之为块级变量ES6才支持

局部变量 只能在定义变量的函数内使用; 全局变量 在任意地方都可以使用。

注意:

函数内的形参也是局部变量,作用域范围就是所在函数。

了解:

函数内不使用关键字 var 声明的变量会被当做全局变量,但不建议这么做,在严格模式下,不使用关键字 var 就声明变量,会报错!

a、b 都是在全局下定义的,所以他们的作用域就是全局,n是在fn中定义的,它的作用域就是fn;


var a=3;
var b=6;
function fn(){
   var n=3;
   console.log(n)
};
console.log(a,b);

在全局下定义的变量,在哪都可以访问到,在私有作用域中定义的变量,在外面是访问不到的

var a=3;

function fn(){
   var b=6;
   console.log(a);
}

fn();
console.log(b);

作用:隔离变量,不同作用域下同名变量不会有冲突

var a = 10,
    b = 20;
function fn(x) {
    var a = 100,
        c = 300;
    console.log('fn()', a, b, c, x)
    function bar(x) {
        var a = 1000,
            d = 400
        console.log('bar()', a, b, c, d, x)
    }

    bar(100)
    bar(200)
}
fn(10)
全局变量和私有变量
  • 全局变量:在全局作用域中定义的变量就是全局变量
  • 私有变量:
    • 形参
    • 在函数私有作用域中定义的变量

1.3 作用域链

① 什么是作用域链

1) 函数会限制变量的作用域范围,而函数内是可以再嵌套函数的,函数的层层嵌套,就形成了一个作用域链

2)作用域链描述的是程序在执行过程当中寻找变量的过程。

② 作用域链寻找变量的过程

当函数内使用某个变量的时候,会按照如下过程找到该变量:

1) 先从自身所在作用域去查找,如果没有再从上级作用域当中去查找,直到找到全局作用域当中。

2)如果其中有找到,就不会再往上查找,直接使用

3)如果都没有找到,那么就会报引用错误提示变量没有定义

③ 注意:

一个变量的作用域只与函数声明的位置有关,与函数调用的位置无关!

function fn(){
  console.log(n);// 自己私有作用域没有这个变量,向上级进行查找,上级window 也没有,就报错
}
fn();
function fn(){
   n=3; // 自己私有作用域中没有,向上级进行查找,上级作用域也没有,就相当于给window.n=3;
}
fn();
console.log(n);
function fn(){
   n=3; // 自己私有作用域中没有,向上级进行查找,上级作用域中有,就是上级作用域的n的值重新改了3
}
var n=2;
fn();
console.log(n);
function fn(){
  console.log(n);// 2
}
var n=2;
fn();
console.log(n);

二、浏览器底层运行机制

var x=12;
let y=13;
z=14;
console.log(window.x);
console.log(window.y);
console.log(window.z);
console.log(x);
console.log(y);
console.log(z);
  • ECStack(Execution context Stack) 执行环境栈(栈内存,从内存中分配出来的一块内存)
  • EC(Execution Context)执行上下文(在编程语言中,代码执行,为了区分全局作用域和函数执行所处不同的作用域,目的是为了区分每个词法作用域下代码的独立性)EC 就是代码执行所处的范围
    • EC(g):全局执行上下文
    • EC(function):函数执行的上下文
  • VO 和AO:在每一个执行上下文中,代码执行的时候,都会存贮一些变量:
    • 全局上下文中的变量存储在VO
    • 私有上下文中的变量存储在AO
  • GO:浏览器把一些内置的属性和方法放到了GO中,并且在全局执行上下文(EC(g))中创建了一个window变量对象,并且让其指向GO

三、变量提升

1、什么是变量提升?

当浏览器开辟出供js执行的栈内存之后,代码并不是立即自上而下执行,而是需要先做一些事情:把当前作用域中带var 和function 的关键字进行提前的声明和定义,这叫做变量提升机制。

var 和function 在变量提升阶段区别:

  • var 在变量提升阶段,是只声明,未定义(不赋值)
  • function 在此阶段是声明和定义都完成。
var a=2;
var b=a;
b=3;
console.log(b)

虽然函数还没有声明定义,但是调用也不受影响

2、变量提升(条件判断)

①不论判断条件是否成立,都会进行变量提升

在当前作用域下,不管判断条件是否成功,都会进行变量提升:

var :还是只声明

function:

  • 新版本浏览器中的function 只是声明,不定义
  • 在老版本中还是声明和定义(仅限判断语句)
console.log(a);
if(1=="1"){
   console.log(a); 
   var a=2;
   console.log(a);
}
console.log(a);

undefined undefined 2 2

console.log(a);
if(1=="2"){
   console.log(a); 
   var a=2;
   console.log(a);
}
console.log(a);

undefined undefined

console.log(fn);
if(1=="2"){
   console.log(fn); 
   function fn(){};
   console.log(fn);
}
console.log(fn);

undefined undefined

console.log(fn);
if(1=="1"){
   console.log(fn); 
   function fn(){};
   fn=3;
   console.log(fn);
}
console.log(fn);

undefined 函数 3 函数

函数是个渣男,以函数为分界线,函数以上的内容会给全局一份

console.log(a);
if("a" in window){
    var a=100;
}
console.log(a);

undefined 100

f=function(){
    return true;
};
g=function(){
    return false;
};
~function(){
 if(g()&&[]==![]){
     f=function(){return false;};
     function g(){
         return true;
     }
 }
}();
console.log(f());
console.log(g());

报错

console.log(fn);
if(1==1){
   console.log(fn);
   function fn(){
       console.log("ok");
   }
}
console.log(fn)

undefined 函数 函数

var a=0;
if(true){
  a=1;
  function a(){}
  a=21;
  console.log(a);
}
console.log(a);

21 1

console.log(num);
console.log(fn);
if([]){
  // 只要进到当前if条件中,会立即对fn进行赋值;
  fn()
  var num=100;
  function fn(){console.log("a")}
}
console.log(fn);

undefined undefined a 函数

②只对等号左边的做变量提升

console.log(fn);
console.log(fn(1,2));
var fn=function (n,m){
    return n+m;
 }
console.log(fn(3,4));
sum();
fn();
var fn=function(){
    console.log(1);
};

function sum(){
    console.log(2);
}

fn();
sum();
console.log(obj.f1);
var obj={
    f1:function(){
       console.log(1)
    }
}

③return 下面的代码进行变量提升,return 后面的代码不进行变量提升

function fn(){
   console.log(a);
   return function f1(){
   }
   var a=3;
}
fn();
function fn(){
  console.log(f2);
  return function f1(){
  }
  function f2(){
    console.log("f2")
  }
}
fn();

④如果变量名字重复

对于var的不会进行重复声明,但是会重新赋值

在变量提升阶段,看到第一行var num ,会声明一个变量num,此时看到第二行还有一个就不用再声明了

var num=2;
var num=3;
console.log(num);

对于function的在变量提升阶段是声明和定义一起完成的,如果遇到重复声明定义的,会进行重新赋值

console.log(fn)
function fn(){
   console.log(1);
}
function fn(){
   console.log(2);
}
function fn(){
   console.log(3);
}
console.log(fn)  
function fn(){    
    console.log(1)
}
var fn=2;       
console.log(fn) 
console.log(num);
var num = 1;
console.log(num);
var num = 2;
console.log(num);
fn();// 4
function fn(){
    console.log(1);
}
function fn(){
    console.log(2);   
}
fn();// 4
function fn(){
    console.log(3);
}
fn=100;
function fn(){
    console.log(4);   
}
fn();

⑤自执行函数在当前所在的作用域中不进行变量提升

自执行函数自己所形成的私有作用域照常进行

function f2(){
   console.log("f2");
}
// 自执行函数在此处不进行变量提升
(function (){
   console.log(a);// undefined, 照常进行变量提升
   var a=3;
})();
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值