草庐IT

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

养肥胖虎 2023-03-28 原文

好家伙,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声明的变量则会)

 

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的不同)的更多相关文章

  1. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  2. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  3. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  4. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  5. ruby - 怎么来的(a_method || :other) returns :other only when assigning to a var called a_method? - 2

    给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R

  6. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

  7. ruby - Rack:如何将 URL 存储为变量? - 2

    我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.

  8. ruby-on-rails - 应用程序的名称是否可以作为变量使用? - 2

    当我创建一个Rails应用程序时,控制台:railsnewfoo我的代码可以使用字符串“foo”吗?puts"Yourapp'snameis"+app_name_bar 最佳答案 Rails.application.class将为您提供应用程序的全名(例如YourAppName::Application)。从那里您可以使用Rails.application.class.parent获取模块名称。 关于ruby-on-rails-应用程序的名称是否可以作为变量使用?,我们在StackOve

  9. java - 为什么 ruby​​ modulo 与 java/other lang 不同? - 2

    我基本上来自Java背景并且努力理解Ruby中的模运算。(5%3)(-5%3)(5%-3)(-5%-3)Java中的上述操作产生,2个-22个-2但在Ruby中,相同的表达式会产生21个-1-2.Ruby在逻辑上有多擅长这个?模块操作在Ruby中是如何实现的?如果将同一个操作定义为一个web服务,两个服务如何匹配逻辑。 最佳答案 在Java中,模运算的结果与被除数的符号相同。在Ruby中,它与除数的符号相同。remainder()在Ruby中与被除数的符号相同。您可能还想引用modulooperation.

  10. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

随机推荐