当前位置: 首页 > news >正文

typescript let和const区别

typescript let和const区别

https://www.cnblogs.com/xyyou/p/11673095.html

全局声明

var声明在函数体外,所声明的变量为全局变量。

var name = "张三";

var所声明的全局变量会作为window的一个属性,可以使用"."来引用。如上例的name引用:

console.log(window.name)

注意:非严格模式下,声明在函数体内的变量,把声明语句的var去掉,那么所声明的变量也是全局变量。

作用域

var变量声明的最大特点是它的作用域为声明语句所在的最近函数体内。

示例:

function f() {
    var message = "Hello, world!";

    return message;
}

var所声明的message变量的作用域范围就是在函数f内。

var声明变量的作用域为函数体的全部,隐含着两个主要问题:变量提升和循环内变量共享。

变量提升

变量提升:JavaScript会把函数内的变量声明提升到函数的最顶部。

示例:

function(){
    var a='a';
    var b='b';
    var c='c';
}

等同于

function(){
    var a,b,c;
    a='a';
    b='b';
    c='c';
}

这样看是貌似没有问题,想一下下面的例子输出结果:

var message='message 1';
(function(){
    console.log(message)
    var message ='message 2';
})()

很多人可能会认为控制台输出的结果是message 1。执行一下会发现,输出的结果为undefined。这是因为变量提升了。

上面的例子实际等同于

var message='message 1';
(function(){
    var message;
    console.log(message)
    message ='message 2';
})()

变量提升有它的优势,但也常常给我们带来一些难以发现的bug。

循环内变量共享

直接看示例:

for (var i = 0; i < 10; i++) {
    setTimeout(function() { console.log(i); }, 100 * i);
}

我们期待的输出结果为依次为0,1,2,3,4,5,6,7,8,9,而实际输出结果都为10。这是因为在循环内共享了变量i,i自增到10结束setTimeOut()里的函数还没有调用,当调用函数时,i值为10,所以输出的结果都为10。

为了解决循环内变量共享,可以考虑使用IIFE。

for (var i = 0; i < 10; i++) {
    (function(i) {
        setTimeout(function() { console.log(i); }, 100 * i);
    })(i);
}

重复声明

在上面的例子

var message='message 1';
(function(){
    console.log(message)
    var message ='message 2';
})()

message是允许重复声明的,重复声明的变量会覆盖之前声明的变量。

let变量声明

let是ES6新增的特性,也是为了解决var变量声明所存在的一些问题,可以说let是更完美的var。

基本用法

let varName = 变量值;

示例:

let name = "张三";

这是和var声明变量类似。

注意:如果let变量声明在全局,它并不会像var声明的变量一样成为window的一个属性。

作用域

let变量声明和var最大的不同点就是变量的作用域不一样。var为函数作用域,而let变量声明的为块作用域(block-scoping)。

块作用域会把声明的变量限定在代码块(如使用{}括起来的代码库)或者for循环内,而不是整个函数体。

function f(input: boolean) {
    let a = 100;

    if (input) {
        let b = a + 1;
        return b;
    }
    // 出错: 'b'属于上面的代码块定义的,在代码块外不能使用。
    return b;
}

let声明的变量不允许在声明前使用,这样解决了var变量提升引起的问题。

(function(){
  console.log(message);    //此处会报错,Uncaught ReferenceError: message is not defined
  let message ='my message';
})()

对于循环内的变量,每次循环都会是捕获值的副本作为运算,而不是共享同一个值,解决了var循环内共享变量的问题。所以前面for循环的例子只需把var改为let即可:

for (let i = 0; i < 10; i++) {
    setTimeout(function() { console.log(i); }, 100 * i);
}

重复声明

let是不允许在同一作用域内重复声明,重复声明会报error: can't re-declare 'x' in the same scope。

function f(x) {
    let x = 100; // error: interferes with parameter declaration
}

function g() {
    let x = 100;
    var x = 100; // error: can't have both declarations of 'x'
}

const变量声明

const变量声明和let类似,但如它的名字所寓意,它定义的是常量,包含了两层意思:

  1. 声明的的变量不能被重复赋值
  2. const声明变量是必须立刻赋值
const numLivesForCat = 9;
numLivesForCat = 10;  //重复赋值,错误

const name;  //错误,声明时没有赋值
name = "张三";  

对于const声明的对象,对象本身是不能被赋值覆盖,但是对象的可修改属性是允许被修改值的。

const numLivesForCat = 9;
const kitty = {
    name: "Aurora",
    numLives: numLivesForCat,
}

// Error
kitty = {
    name: "Danielle",
    numLives: numLivesForCat
};

// all "okay"
kitty.name = "Rory";
kitty.name = "Kitty";
kitty.name = "Cat";
kitty.numLives--;

 

 

 

 

相关文章:

  • 关于TypeScript中null,undefined的使用
  • typescript 类型断言
  • TypeScript: this bind 和 回调的正确用法
  • TypeScript基础入门之高级类型的可null类型
  • Blender 插件之 Blender for UE4
  • 7月底发布的官方插件:从 Blender 到 Unreal
  • 使用Blender的UEFY插件创建兼容UE4和Rigify的人物骨骼
  • UE4 Pak加密(Encrypt)
  • UE4 Pak 相关知识总结
  • typescript 函数参数类型不做检查
  • Standalone Dedicated Server
  • 物理网络正常而HttpWebResponse的GetResponse依然经常超时的解决办法
  • C# Thread.Sleep(0)有什么用?
  • HttpWebRequest的timeout和ReadWriteTimeout
  • HttpWebRequest.ReadWriteTimeout 属性
  • 【Linux系统编程】快速查找errno错误码信息
  • Apache Zeppelin在Apache Trafodion上的可视化
  • JAVA多线程机制解析-volatilesynchronized
  • Python语法速览与机器学习开发环境搭建
  • Spark RDD学习: aggregate函数
  • 从setTimeout-setInterval看JS线程
  • 机器学习中为什么要做归一化normalization
  • 前端设计模式
  • 入手阿里云新服务器的部署NODE
  • 微信小程序填坑清单
  • 小程序开发之路(一)
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • #{} 和 ${}区别
  • $().each和$.each的区别
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (算法)求1到1亿间的质数或素数
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (一)基于IDEA的JAVA基础12
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)负载均衡,回话保持,cookie
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • .axf 转化 .bin文件 的方法
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .Net IE10 _doPostBack 未定义
  • .Net(C#)自定义WinForm控件之小结篇
  • .Net环境下的缓存技术介绍
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示
  • @html.ActionLink的几种参数格式
  • [ C++ ] STL_stack(栈)queue(队列)使用及其重要接口模拟实现
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛
  • [17]JAVAEE-HTTP协议
  • [20161214]如何确定dbid.txt