varletconst关键字的详细解读

Posted Mr-programming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了varletconst关键字的详细解读相关的知识,希望对你有一定的参考价值。

var关键字

作用:后接变量名,用来定义变量

var num

这里通过var关键字定义了一个num变量,我们没有给num初始化,此时num的值为undifined

var str ="kobe"
str=123

这里通过var关键字定义了一个保存“kobe”字符串值的 变量str,str的数据类型不是被规定死的,第二行的代码改变了存储值得同时改变了数据类型(改变类型是不推荐的)

声明范围(函数作用域)

  • 全局作用域下
var str = "hello,word"
function test() {
    console.log(str)
}
test() //hello ,world

在全局作用域下通过var关键字定义的str变量为全局变量

var num1 = 1
console.log(window.num1, window.num2)	//1,undefined
var num2 = 2
console.log(window.num1, window.num2)	//1,2

这里要注意使用var全局声明的变量会成为window对象的属性

  • 函数体内:
function test(){
	var str="hello, world"
}
console.log(str)    //报错!

在函数体内通过var关键字定义str变量,函数被调用时会创建这个变量并给其赋值,同样在函数被执行完毕后变量被销毁。也就是说这个变量只在函数作用域内有效,在函数体外部我们是访问不到的。

  • 函数体内省略var关键字
test()
console.log(str)  //hello, world
function test() {
    str = "hello,word"
}    

同样是在函数体内定义,不同的是省略了var关键字,test函数被调用时(只要被调用一次)就会创建全局变量str,该变量和在直接全局作用域下定义的一样都会成为window的属性

变量提升

  • 例1
console.log(str)    //undefined
var str = "hello,word"
console.log(str) 	//hello, world

这里不会报错是相当于执行了如下代码

var str
console.log(str)	//undefined
str="hello, world"
console.log(str)	//hello, world
  • 例2
var num = 1
var num = 2
console.log(num)	//2
var num = 3
var num = 4
console.log(num)	//4

相当于执行了如下代码

var num
num=1
num=2
console.log(num)	//2
num=3
num=4
console.log(num)	//4

这就是var关键字存在的变量“提升”,也就是把所有变量声明拉倒作用域的顶部。


let关键字

let关键字和var关键字的作用类似,不过相比于var,let显得更加的严谨,let关键字不存在“变量提升”,let关键声明的作用域范围是块作用域而var关键字是函数作用域

作用:后接变量名,定义变量

let str
str = 123
console.log(str)	//123
str = "kobe"
console.log(str)	//kobe

声明范围(块级作用域)

{
     var num = 1
}
console.log(num)	//1
{
    let num = 1
    console.log(num)	//1
}
console.log(num)	//报错!

正如开头所说的let关键字不同于var关键字 他的声明范围为块级作用域,在作用域外是访问不到该变量的

var num=1
{
    let num=2
    console.lgo(num)	//2
}
{
    var num = 1
    let num = 2
    console.log(num)	//报错
}
{
    let num=1
    let num=2
    console.log(num)	//报错
}

对于let关键字在同一块级作用域中,相同标识符会报错

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

暂时性死区

相比于var关键字,let声明的变量不会在作用域中被提升。

console.log(num)	//报错! 这里不会和var一样打印undefined
let num=1

在num被声明前执行的一瞬间成为“暂时性死区”


经典例题

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

通过var关键字定义的迭代变量会渗透到循环体外部

for(let i=0;i<5;i++){
    
}
console.log(i)		//报错!

迭代变量的作用域是循环体这个块级作用域,let关键字定义的变量范围正是块级作用域,所以外部访问会报错

for (var i = 0; i < 5; i++) {
    console.log(i)
}
//0 1 2 3 4


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

加了定时器函数后打印结果变了,这是因为在退出循环时迭代变量保存的是导致循环退出的值:5,在之后的执行超时函数时所有的i都是同一个值:5

for(let i=0;i<5;i++){
    setTimeout(()=>{console.log(i)},0)
}
//打印结果0 1 2 3 4

这是因为后台会为个迭代循环声明一个新的迭代变量,他们都是互相独立的,每一个超时函数时打印的都是不同的变量实例


const关键字

const关键字和let是类似的,唯一 一个重要区别是const关键字声明变量时必须初始化,并且在修改const定义的变量时会报错(这里指的是修改内存地址),在修改一个对象内部的一个属性时是不会报错的

以上是关于varletconst关键字的详细解读的主要内容,如果未能解决你的问题,请参考以下文章

DDIM代码详细解读:数据集加载类别条件信息读取关键超参数解析

DDIM代码详细解读:数据集加载类别条件信息读取关键超参数解析

DDIM代码详细解读:关键参数计算损失函数设计添加时间步长信息归一化设计

DDPM代码详细解读:数据集准备超参数设置loss设计关键参数计算

DDPM代码详细解读:数据集准备超参数设置loss设计关键参数计算

使用varletconst声明变量