js基础复习:变量

引入

首先,ECMAscript变量是松散类型的

变量可以用于保存任何数据类型的值

var a=18;
a="yes";//合法,a被修改为字符串,

这也是我刚开始不习惯js的原因,因为这一点和java,c等不一样

varlet(ES6引入)是俩种可以声明变量的关键字

(另外一种是const,本文不讲)

var

var a="123";

用var声明一个a变量

注意!

a虽然被初始化为字符串,但却可以修改为其他数据类型

也就是说初始化只是一个赋值操作

对于var来说最大的特点就是变量提升函数作用域

也是它不被待见的地方(doge)

函数作用域

var声明的变量的作用域为该函数作用域

比如下面的例子:

function add(){
	var a=1;
    console.log(a);//1
}
console.log(a);//报错,a未声明

该变量会在函数退出后被销毁

如果定义在整个js文件或script标签中

则成为全局变量,成为window对象的属性

var的变量提升

🎗️所谓“提升”,也就是把所有变量声明拉到函数作用域的顶部

在这里插入图片描述

这个例子中c变量明明在log后声明并赋值,但却可以输出我们值,就是因为var变量提升

变量提升造成了什么?

1.没有let的暂时性死区(见本文的let)

2.可以重复定义

是不是好事?

不见得是好事,因为上面这个例子正常人都不会写出来

我们更习惯先声明一个变量再去使用它

所以es6出现了let

let

块作用域

与var的函数作用域不同

let声明的范围是块作用域,js引擎解析代码时离开作用域就销毁这个变量

简单说一下二者区别(不深入):

块作用域就是单纯{}包着的作用域

而函数作用域就是函数{}包着的作用域

比如

if(true){
    var age1=18;
    let age2=20;
}
console.log(age2);//ReferenceError: age2 is not defined

这个例子中,age2是在if作用域用let声明的。在外访问就报错

没有变量提升才是好事

let没有var的变量提升,这给它带来了什么?

1.暂时性死区

详细介绍JS中“暂时性死区”的概念-js教程-PHP中文网

2.不能重复定义

没有变量提升的let更符合我们的编程习惯

比如我们习惯于先声明变量再使用

或者是不小心声明了名字相同的变量

所以我们更喜欢let

const

const和let基本相同,唯一一个重要的区别就是用它声明变量时必须初始化,并且不能修改

const age=18;
age=19;//TypeError:不能给常量赋值

但是,“不能修改”指的是不能修改指向的变量的引用

换句话说,如果const变量是一个对象,则可以修改该对象内部的值

const person={};
person.age=19;//ok
person={age:18;}//error

对三者如何选择?

1.不使用var

我们需要变量有它自己明确的作用域,声明位置。

let更符合我们的习惯。

2.const优先,let次之

使用const声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作。

当发现这个值需要修改时,再把声明改为let不迟。

本期附带:for循环中的let声明

我们都知道在for循环中的迭代变量要用let声明

为什么?

for(var i=0;i<5;i++){
    console.log("for循环");
}
//for循环*5

上述例子证明var声明迭代变量,for循环次数也是我们期待的

那为什么不用var呢?

var的情况

看一张图就明白了

在这里插入图片描述

上述过程分析:

假如我们用var声明这个i,底层实现就是

for循环是一个大的作用域(图中的父作用域)

在父作用域中var i=0;

然后进行判断进入子作用域,然后对函数声明,赋值给a

i++,然后跳出循环(跳出父作用域)

跳出循环后,i就成为那个循环结束标志的那个值了

调用函数时,输出的i就是3了(不符合要求)

let的情况

那为什么用let呢?

js红宝书有一句话:

而在let声明迭代变量时,js引擎在后台会为每个迭代循环声明一个新的迭代变量,适用于所有风格的for循环

看一下下面这个图
在这里插入图片描述

上述过程分析:

假如我们拿let声明这个i,底层实现就是

for循环是一个大的作用域(图中的父作用域)

在父作用域中let i=0;

然后进行判断进入子作用域,然后对函数声明,赋值给a

但是重新let一个k,将i赋值给k,这就是 js引擎给你重新声明的新的迭代变量

i++,然后跳出循环(跳出父作用域)

输出的那个k就是子作用域的那个新的迭代变量,即你所期望的值

总结:

for循环中一定用let声明迭代变量

因为那句话:

而在let声明迭代变量时,js引擎在后台会为每个迭代循环声明一个新的迭代变量,适用于所有风格的for循环

和那句话:

let声明的范围是块作用域

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程就是n踢r

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值