第一百零六篇:变量的不同声明(var,let和const的不同)

第一百,六篇,变量,不同,声明,var,let,const · 浏览次数 : 139

小编点评

**JS高级程序设计第三章学习笔记1:变量 ECMAScript 变量** **1.变量** * JS 中的变量是松散类型的,这意味着它们可以保存任何类型的数据。 * 每个变量仅仅是一个用于保存任意值的命名占位符。 * 有 3 个关键字可以声明变量:`var`、`const` 和 `let`。 **2.`var`声明** * `var` 在 ECMAScript 所有版本中都可以使用。 * `var`声明用 `var`声明的变量可以保存任何类型的值,即使变量没有进行初始化。 **3.`let`声明** * `let` 在 ECMAScript 6 及更晚版本的 JavaScript 中使用。 * `let`声明的变量只能在块作用域中声明。 * 与 `var` 声明相比,`let`声明的变量在声明时会被提升到函数作用域的顶部。 **4.`const`声明** * `const` 在 JavaScript 中使用,与 `var` 和 `let` 相同。 * `const`声明的变量无法修改。 **5.`for`循环中的let和var** * 使用 `let` 和 `var`声明的变量分别来跑一次 `for`循环。 * 在退出循环时,迭代变量保存的是导致循环退出的值。 * 使用 `let`声明的迭代变量在循环退出时还会被定义。 **6.`var`声明的特殊情况** * 在 `for` 循环中使用 `var`声明的变量时,声明会被提升,并自动在作用域顶部合并为一个声明。 * 这会导致多次 `var` 声明导致报错。 **7.其他** * `const` 和 `var` 的作用域不同:`const` 的作用域为块作用域,`var` 的作用域为函数作用域。 * `const`声明的变量无法引用 `window` 对象的属性,而 `var` 声明的变量可以。

正文

好家伙,JS基础接着学,

本篇内容为《JS高级程序设计》第三章学习笔记



1.变量

 

ECMAScript 变量是松散类型的,意思是变量可以用于保存任何类型的数据

(确实松散,不像C或C++那样,分int,float,char等等...,一个变量可以用来保存任何类型的数据)

每个变量只不过是一个用于保存任意值的命名占位符。有3个关键字可以声明变量:

var、const 和let

其中,var 在 ECMAScript的所有版本中都可以使用,而const和1et只能在ECMAScript 6及更晚的版本中使用。 

 

2.var声明

用var声明的变量可以保存任何类型的值

在不进行初始化的情况下,变量会保存一个特殊值undifined

var panghu;
console.log(panghu);

看图:

 

 

 

 

2.1.var声明作用域

function test(){
    var panghu = "panghu";
}
test();
console.log(panghu);

看图:

 

 

 

在函数内忽略var声明变量,可以声明一个全局变量

function test(){
    panghu = "panghu";
}
test();
console.log(panghu);

看图:

 

 

 

 至此,我们可以得出:

使用var操作符定义的变量会成为包含它的函数的局部变量

(人话翻译:在函数内使用var声明变量,那么该变量的作用域在该函数内)

 

2.2.var声明提升

使用var关键字声明的变量会自动提升到函数作用域的顶部

(仅仅是声明提升,不包含赋值操作)

(代码拿前面的掉一下顺序就好了)

 

 

 

 在这里我们可以看到,panghu在console.log(panghu);前就已经被声明了,

再看一个例子

 

 

两次输出内容不同

 

由此,我们知道

function test(){
    var panghu = "panghu";
    console.log(panghu);
}
test();

function test(){
    var panghu;
    console.log(panghu);
    panghu = "panghu";
}
test();

两者等价

这便是"变量提升"了

 

 

3.let声明

let和var的作用差不多,但也有所区别,

区别1:var声明的范围是函数作用域,而let声明的范围是块作用域,

举例子:

if(1){
    var panghu = "panghu";
    console.log("第一次输出"+panghu);
}
console.log("第二次输出"+panghu);

if(1){
    let kunkun = "kunkun";
    console.log("第三次输出"+kunkun);
}
console.log("第四次输出"+kunkun);

看图

 

 

 一个例子很好的说明了,

let声明的变量,到了块作用域外就寄了

而var声明的变量,依旧好好活着

 

这两个关键字声明的并不是不同类型的对象,

他们只是指出变量在相关作用域如何存在

 

 

3.1.对声明冗余(重复声明同一变量)报错不会因混用let和var影响

 

 

 (四个排列组合告诉你,不要重复声明变量)

 

3.2.暂时性死区

 区别二:let没有"变量提升"

console.log(panghu);
var panghu;

console.log(kunkun);
let kunkun;

 

 

 

 (let声明的变量,寄)

在let声明之前执行的瞬间被称为"暂时性死区",

在此阶段引用任何后面才声明的变量都会报错:ReferenceError

 

3.3.全局声明

区别三:

与var关键字不同,使用let 在全局作用域中声明的变量不会成为window 对象的属性(var声明的变量则会)

 

var panghu ="panghu";
console.log(window.panghu);

let kunkun ="kunkun";
console.log(window.kunkun);

 

 

 

 

补充:

3.4.条件声明

在使用var 声明变量时,由于声明会被提升,JavaScript引擎会自动将多余的声明在作用域顶部合并为一个声明。
因为let的作用域是块,所以不可能检查前面是否已经使用let声明过同名变量,同时也就不可能在没有声明的情况下声明它。

我们知道,var可以多次声明,而let多次声明会报错,因此,let是更为严谨的

 

4.const 声明

const的行为基本与let相同,两者作用域同样为"块"

但仍有区别(怎么可能会没有区别)

声明变量时必须同时初始化变量,

const声明的变量无法修改,

有趣的是,如果const变量引用的是一个对象,

那么修改这个对象内部的属性并不违反const的"禁止修改"

const panghu ={};
panghu.age = 20;
console.log(panghu.age);

看图:

 

 

 这样的写法是完全可行的

 

 

5.for循环中的let和var

 

我们用let和var声明的变量分别来跑一次for循环

 

 

 一切正常;

然后我们改一下

for(var i=0;i<8;i++){
    setTimeout(()=>console.log(i),0);
}

for(let j=0;j<8;j++){
    setTimeout(()=>console.log(j),0);
}

看图:

 

 

 

之所以会这样,是因为在退出循环时,迭代变量保存的是导致循环退出的值:8。

在之后执行超时逻辑时,所有的i都是同一个变量,因而输出的都是同一个最终值。

 

而在使用let声明迭代变量时,JavaScript引擎在后台会为每个迭代循环声明一个新的迭代变量。

)每个setTimeout 引用的都是不同的变量实例,所以console.log输出的是我们期望的值,

也就是循环执行过程中每个迭代变量的值。

(神奇的JS)

 

That's all.

 

与第一百零六篇:变量的不同声明(var,let和const的不同)相似的内容:

第一百零六篇:变量的不同声明(var,let和const的不同)

JS关于变量的声明,变量提升,暂时性死区

第一百零五篇:变量的原始值和引用值

好家伙,JS基础接着学, 本篇内容为《JS高级程序设计》第四章学习笔记 1.原始值和引用值 ECMAScript变量可以包含两种不同类型的数据:原始值和引用值。原始值(primitive value)就是最简单的数据,引用值(reference value)则是由多个值构成的对象。 在把一个值赋给变

第一百零七篇:基本数据类型(undefined,null,boolean类型)

好家伙, 本篇内容为《JS高级程序设计》第三章学习笔记 1.数据类型 ECMAScript有6种简单数据类型(称为原始类型): Undefined, Null, Boolean, Number, String和Symbol。 Symbol (符号)是ECMAScript6新增的。还有一种复杂数据类型

第一百零八篇:最常用的基本数据类型(Number类型)

最常用的基本数据类型(Number类型)

第一百一十篇:内存泄漏和垃圾回收(JS)

好家伙,本篇内容为《JS高级程序设计》第四章的学习笔记 1.内存泄露 1.1.什么是内存泄漏? 内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。 内存泄漏缺陷具有隐蔽性、积累性的特征,比其

第一百一十一篇:基本引用类型Date

好家伙,本篇为《JS高级程序设计》第五章的学习笔记 1.基本引用类型 引用值(或者对象)是某个特定引用类型的实例,在ECMAScript中,引用类型是把数据和功能组织到一起的结构,(像极了“类”) 经常被人错误的称作“类”。 虽然从技术上讲JavaScript是一门面向对象语言,但是ECMAScri

第一百一十四篇: JS数组Array(三)数组常用方法

好家伙,本篇为《JS高级程序设计》第六章“集合引用类型”学习笔记 1.数组的复制和填充 批量复制方法 copyWithin(),以及填充数组方法fill()。 这两个方法的函数签名类似,都需要指定既有数组实例上的一个范围,包含开始索引,不包含结束索引。 使用这个方法不会改变数组的大小。 1.1.fi

第一百一十五篇: JS集合引用类型Map

好家伙,本篇为《JS高级程序设计》第六章“集合引用类型”学习笔记 1.Map ECMAScript6以前,在JavaScript中实现“键/值”式存储可以使用object来方便高效地完成,也就是使用对象属性作为键,再使用属性来引用值。 但这种实现并非没有问题,为此TC39委员会专门为“键/值”存储定

第一百一十六篇: JavaScript理解对象

好家伙,本篇为《JS高级程序设计》第八章“对象、类与面向对象编程”学习笔记 1.关于对象 ECMA-262将对象定义为一组属性的无序集合。严格来说,这意味着对象就是一组没有特定顺序的值。 对象的每个属性或方法都由一个名称来标识,这个名称映射到一个值。正因为如此(以及其他还未讨论的原因),可以把 EC

第一百一十二篇: JS数组Array(一)数组基本用法

好家伙, 1.数组 Array应该就是ECMAScript中最常用的类型了。ECMAScript数组跟其他编程语言的数组有很大区别。 跟其他语言中的数组一样,ECMAScript 数组也是一组有序的数据, 但跟其他语言不同的是,数组中每个槽位可以存储任意类型的数据。 这意味着可以创建一个数组,它的第