变量声明---let,const,解构

2023-06-15,,

let在很多方面与var是相似的,但是可以帮助大家避免在JavaScript里常见一些问题。 const是对let的一个增强,它能阻止对一个变量再次赋值。

块作用域

当用let声明一个变量,它使用的是词法作用域块作用域

(1)不同于使用 var声明的变量那样可以在包含它们的函数外访问,块作用域变量在包含它们的块或for循环之外是不能访问的。

function f(input: boolean) {
let a = ;
if (input) {
// Still okay to reference 'a'
let b = a + ;
return b;
}
// Error: 'b' doesn't exist here
return b;
}

(2)拥有块级作用域的变量的另一个特点是,它们不能在被声明之前读或写。

注意一点,我们仍然可以在一个拥有块作用域变量被声明前获取它。 只是我们不能在变量声明前去调用那个函数。 如果生成代码目标为ES2015,现代的运行时会抛出一个错误;然而,现今TypeScript是不会报错的。

(3)重定义及屏蔽

const 声明

let声明相似,但是就像它的名字所表达的,它们被赋值后不能再改变。 换句话说,它们拥有与 let相同的作用域规则,但是不能对它们重新赋值。

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--;

  除非你使用特殊的方法去避免,实际上const变量的内部状态是可修改的。TypeScript允许你将对象的成员设置成只读的。

解构

(1)数组结构

(2)对象解构

let o = {
a: "foo",
b: ,
c: "bar"
}
let { a, b } = o;
通过 o.a and o.b 创建了 a 和 b 。 注意,如果你不需要 c 你可以忽略它。

就像数组解构,你可以用没有声明的赋值:

({ a, b } = { a: "baz", b:  });
注意,我们需要用括号将它括起来,因为Javascript通常会将以 { 起始的语句解析为一个块。

(3)属性重命名

let { a: newName1, b: newName2 } = o;
这里的语法开始变得混乱。 你可以将 a: newName1 读做 "a 作为 newName1"。 
=====================
let newName1 = o.a; let newName2 = o.b; 令人困惑的是,这里的冒号不是指示类型的。 如果你想指定它的类型, 仍然需要在其后写上完整的模式。
let {a, b}: {a: string, b: number} = o;

(4)默认值----默认值可以让你在属性为 undefined 时使用缺省值:

function keepWholeObject(wholeObject: { a: string, b?: number }) {
let { a, b = } = wholeObject;
}

(5)函数声明

简单的情况:

type C = { a: string, b?: number }
function f({ a, b }: C): void {
// ...
}

但是,通常情况下更多的是指定默认值,解构默认值有些棘手。

首先,你需要知道在设置默认值之前设置其类型。

function f({ a, b } = { a: "", b:  }): void {
// ...
}
f(); // ok, default to { a: "", b: 0 }

其次,你需要知道在解构属性上给予一个默认或可选的属性用来替换主初始化列表。 要知道 C 的定义有一个 b 可选属性:

function f({ a, b =  } = { a: "" }): void {
// ...
}
f({ a: "yes" }) // ok, default b = 0
f() // ok, default to {a: ""}, which then defaults b = 0
f({}) // error, 'a' is required if you supply an argument

要小心使用解构。尤其当存在深层嵌套解构的时候,就算这时没有堆叠在一起的重命名,默认值和类型注解,也是令人难以理解的。 解构表达式要尽量保持小而简单。 你自己也可以直接使用解构将会生成的赋值表达式。

(6)展开----许你将一个数组展开为另一个数组,或将一个对象展开为另一个对象。

let defaults = { food: "spicy", price: "$$", ambiance: "noisy" };
let search = { ...defaults, food: "rich" };

对象的展开像数组展开一样,它是从左至右进行处理,但结果仍为对象。这就意味着出现在展开对象后面的属性会覆盖前面的属性。

let defaults = { food: "spicy", price: "$$", ambiance: "noisy" };
let search = { food: "rich", ...defaults };

那么,defaults里的food属性会重写food: "rich",在这里这并不是我们想要的结果。

对象展开还有其它一些意想不到的限制。 

首先,它只包含自身的可枚举的属性。 首先,当你展开一个对象实例时,你会丢失其方法:

class C {
p = ;
m() {
}
}
let c = new C();
let clone = { ...c };
clone.p; // ok
clone.m(); // error!

其次,TypeScript编译器不允许展开泛型函数上的类型参数。这个特性会在TypeScript的未来版本中考虑实现。

变量声明---let,const,解构的相关教程结束。

《变量声明---let,const,解构.doc》

下载本文的Word格式文档,以方便收藏与打印。