js高级02变量提升、闭包(1)

变量提升机制
1.数据值操作机制

2.变量提升机制
+什么是变量提升
+带var和不带的区别
+等号左边变量提升
+条件判断下的变量提升
+重名问题的处理

3.ES6中let不存在变量提升
+不允许重复定义
+暂时性死区
+不存在变量提升

1.为什么一般都把Js放到body的末尾
2.放在HEAD中可个可以?如何双到HEAD中也可以大境山从PDi/的效果?
3.SCRIPT标签中有两个属性: defer / async 的作用

1.js数据操作(渲染)

复习
var a = 12的过程
1. 先声明一个变量a,没有赋值(默认值是undefined)
2. 在当前作用域中开辟一个位置存储12这个值
3. 让变量a和12关联在一起(定义:赋值)

var a = 12


var b = a;
b = 13;
console.log(a);//12

var ary1 = [12, 23];
var ary2 = ary1;
ary2.push(100);
console.log(ary1);//[12,23,100]

在这里插入图片描述

任意数求和

 console.log(sum('10', 10, 20, 'AA'));

 function sum() {
     var total = 0;
     for (var i = 0; i < arguments.length; i++) {
         if (isNaN(arguments[i]) == false) {
             total = total + parseFloat(arguments[i]);
         }
     }
     return total;
 }

在这里插入图片描述

2.js变量提升(ES3/ES5)

  console.log(a);    输出undefined,不会报错
  var a =12;

变量提升:==当栈内存(作用域)形成之后,JS代码自上而下执行之前,==浏览器首先会把所有带 “var”/“function” 关键词的进行提前 “声明” 或者 “定义” ,这种预先处理机制称之为 “变量提升”

声明(declare):var a (默认值undefined)
定义(defined):a=12 (定义其实就是赋值操作)

[变量提升阶段]
带“var”的只声明未定义
带“function”的声明和赋值都完成了

变量提升只发生在当前作用域(例如:开始加载页面的时候只对全局作用域下的进行提升,因为此时函数中存储的都是字符串而己)

在全局作用域下声明的函数或者变量是"全局变量”,同理,在私有作用域下声明的变量是"私有变量“

浏览器很懒,做过的事情不会重复执行第二遍,也就是,当代码执行遇到创建函数这部分代码后,直接的跳过即可(因为在提升阶段就已经完成函数?的赋值操作了)

执行顺序

1.形参赋值2.变量提升 3.代码执行(私有作用域)

全局变量提升阶段
var a;var b;sum=0X88888(堆内存地址空间)


-----------------------------------------------
1.形参赋值2.变量提升 3.代码执行(私有作用域)
私有变量提升阶段 
sum()函数

var total;var i; var item;

--------------------------------------------------------------
var a = 12
var b = a;
b = 13;
console.log(a);//12

var ary1 = [12, 23];
var ary2 = ary1;
ary2.push(100);
console.log(ary1);//[12,23,100]

console.log(sum('10', 10, 20, 'AA'));

function sum() {
    var total = 0;
    for (var i = 0; i < arguments.length; i++) {
        if (isNaN(arguments[i]) == false) {
            total = total + parseFloat(arguments[i]);
        }
    }
    return total;
}

在这里插入图片描述

3.js带var和不带var的区别

全局变量

加var的本质是变量,存在变量提升
不加var的本质是window的属性,不存在变量提升

全局变量和window中的属性存在映射机制(一个改变另一个也改变)

加var

在全局作用域下声明一个变量,也相当于给window全局对象设置了一个属性,变量的值就是属性值
(私有作用域中声明的私有变量和window没啥关系)

console.log(a);     有属性a,由于变量提升机制,没有赋值 undefined
console.log('a' in window);  true  在变量提升阶段,在全局作用域中声明了一个变量A,此时就已经把A当做属性赋值给window了,只不过此时还没有给A赋值,默认值uindefined

console.log(window.a);     有属性a,由于变量提升机制,没有赋值 undefined
var a = 12;       全局变量值修改,wIN的属性值也跟着修改
console.log(a);    全局变量A  12
console.log(window.a);    window的一个属性名A 12

全局变量和window下的属性存在映射机制

不加var,给window对象新增属性

  console.log(a);  //Uncaught ReferenceError: a is not defined
  console.log('a' in window);//false

  console.log(window.a);  //undefined
  a = 12;     //等价于window.a = 12  //给window添加属性a  
  console.log(a);  //12
  console.log(window.a); //12
var a= 12,b = 13;   这样写b是带varvar a = b = 12 ;    这样写b是不带var,a是带var
等价于var a=12; b=12;

私有变量

私有作用域中带var和不带也有区别:

1.带var的在私有作用域变量提升阶段,都声明为私有变量,和外界没有任何的关系
2.不带var不是私有变量,会向它的上级作用域查找,看是否为上级的变量,不是,继续向上查找,一直找到window为止(我们把这种查找机制叫做:“作用域链”)
3.在私有作用域中操作的这个非私有变量,是一直操作别人的


console.log(a, b);//undefined、undefined
var a = 12, b = 12;
function fn() {
    console.log(a, b);  //undefined、12
    var a = b = 13;/*var a=13;  b=13*/
    console.log(a, b);  //13,13
}
fn();
console.log(a, b); //12,13

在这里插入图片描述

4.js作用域链的扩展

ES5 var

function fn() {
    var a = 12;
    b = 13; // 在作用域链查找的过程中,如果找到win也没有这个变量,相当于给win设置了一个属性B,(window.b=13)
    console.log('b' in window);    //true


    console.log(a, b);//12 13
}
fn();
console.log(b);  //13
console.log(a);  //Uncaught ReferenceError: a is not defined

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ES6 let

 let a = 12;
 console.log(a, window.a);//12 undefined

5.只对等号左边变量提升

sum();  可以正常执行,因为存在变量提升。在代码没执行前,在全局作用域中将sum()函数声明+定义

console.log(fn);  undefined

变量提升 var fn;
fn();//报错 fn is not a function  

匿名函数函数表达式(常用)
var fn = function () {//只对等号左边变量提升
    console.log(11);
}

普通函数
function sum() {
    console.log(22);
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值