TypeScript learning two (variable declaration)

In the previous article, we learned about the installation and use of TS and the basic types . This article continues to learn about type inference and variable declaration.

type inference

The core function of TS is that 类型检查we need to add type annotations to variables or methods to indicate the data type. When no type annotation is provided, the TS compiler will use it 类型推断to infer the type.

var num = 2; // 类型推断为 number
num = "12"; // 编译错误,不能将类型“string”分配给类型“number”

If the type cannot be inferred due to lack of declaration, then its type is assumed to be the default dynamic anytype .

Type assertion Type Assertion

In some cases, we will be clearer than TS The exact type can be used to 类型断言manually specify the type of a value, which allows the variable to change from one type to another. It has no runtime impact, it just 编译阶段works.

Type assertions come in two forms, the first is 尖括号syntax:

<type> value

The second is asthe syntax :

value as type

for example:

// typescript
// 类型推断为 string
var str = '1'
// 成功,类型断言先转成any,再转成number
var str2: number = <number><any>str
// 失败,string直接转成number会报错
var str3: number = <number>str
// 编译为
// javascript
var str = '1';
var str2 = str;

From the above example, we can know that the use of type assertion conversion requires an association between the two types. For example, if stringit is anya subset of , then they can be converted to each other, and if numberit is anya subset of , then they can also be converted to each other, so they str2can be successfully assigned ; but stringthe numbertwo types do not sufficiently overlap to be convertible. Type assertions can only be used if the type is specified, and baseless assertions are dangerous.

variable declaration

The variable declaration methods of TS and JS are the same. Here is a brief introduction to the relationship and difference between var, let and const.

was

All the while, we use varstatements to declare an 函数范围or 全局范围variable.

// 全局范围
var a = 1;
function fn() {
    
    
  // 函数范围
  var message = "Hello, world!";
  return message;
}

var has some strange properties, there is a feature called 变量提升, no matter where you declare the variable, it will be processed before any code is executed:

function fn(flag) {
    
    
  if (flag) {
    
    
    var x = 10;
  }

  return x;
}

fn(true); // 10
fn(false); // undefined

The function fn above is equivalent to

function fn(flag) {
    
    
  // 变量x的初始值为 undefined
  var x;
  if (flag) {
    
    
    x = 10;
  }

  return x;
}

In TS, the above code adds verification, although it can still run, it will give a prompt

// typescript
function fn(flag: boolean) {
    
    
  if (flag) {
    
    
      var x = 10;
  }

  return x; // 报错:在赋值前使用了变量“x”
}

another example:

var a = [];
for (var i = 0; i < 10; i++) {
    
    
  a[i] = function () {
    
    
    console.log(i);
  };
}
a[1](); // 输出10

This is because what is passed into the function during the loop 变量iis 10 全局变量after forthe loop ends, iand the output of the calling function is 10.

In addition, using var can repeatedly declare the same variable without reporting an error:

var a;
var a;
var a;

let

Because of some problems varwith , ES6a new letstatement . Except for the name difference, itlet is written in the same way as .var

let hello = "Hello!";

When letdeclaring a variable with , it uses the 块作用域. Unlike variables vardeclared which can be accessed outside their enclosing function, variables cannot be accessed outside 块作用域their enclosing or loop. forLike the example above:

function fn(flag) {
    
    
    if (flag) {
    
    
        let x = 10;
    }

    return x;
}

fn(true); // 10
fn(false); // 报错:x is not defined

another example:

let a = [];
for (let i = 0; i < 10; i++) {
    
    
  a[i] = function () {
    
    
    console.log(i);
  };
}
a[1](); // 输出1

Another characteristic of variables with block scope is that they cannot be 声明之前read or written again.

// 报错:Cannot access 'a' before initialization
a++;
let a;

The above does not report an error saying aundefined , but that it cannot be accessed before initialization. It means that the variable a exists in scope, but the area up to the code that declares it belongs to 暂时性死区, so it cannot be accessed. In TS, the above code gets an error 声明之前已使用的块范围变量“a”.

注意At one point, we can still access a block-scoped variable before it is declared. It's just that we can't call that function before the variable declaration. The modern runtime throws an error if the generated code targets ES2015.

function foo() {
    
    
    // 可以成功捕获到a
    // 运行时会报错:Cannot access 'a' before initialization
    return a;
}

// 不能在'a'被声明前调用'foo'
// 运行时应该抛出错误
foo();

let a;

The above code will not prompt and report an error in TS, so you need to pay attention.

As we mentioned above, var can be used for repeated declarations, but let is not so relaxed:

let a;
let a;

The above code reports an error at runtime: Identifier 'a' has already been declared, and it will also prompt in TS 无法重新声明块范围变量“a”that it can only be declared once in the same block scope.

It is not required that two declarations be block-scoped for TypeScript to give a false warning:

// case1
function f(x) {
    
    
  // TS警告:标识符“x”重复
  let x = 100; // 运行时报错:Identifier 'x' has already been declared
}
// case2
function g() {
    
    
  // TS警告:无法重新声明块范围变量“x”
  let x = 100;
  var x = 100; // 运行时报错:Identifier 'x' has already been declared
}

If you want to declare a block-scope variable with the same name in function scope, you need to put it in a different block:

function fn(flag, x) {
    
    
  if (flag) {
    
    
    let x = 100;
    return x;
  }

  return x;
}

fn(false, 0); // 0
fn(true, 0);  // 100

The act of introducing a new name in a nested scope is called屏蔽

const

constStatement is another way of declaring variables, which is similar to the way of letdeclaring , the difference is that after declaring and assigning 不能重新赋值:

const role = 'Tom'
// TS警告:无法分配到 "role" ,因为它是常数
role = 'Jerry'

The above code reports an error when running:Assignment to constant variable

The value of a const reference cannot be changed, but the internal state can be changed:

const person = {
    
    
  name: 'Tom'
}
// 失败
person = {
    
    
  name: 'Jerry'
}
// 成功
person.name = 'Jerry'

In general, letit is close to the way of constuse , the basic principle is that if a variable does not need to be reassigned, it is used const, and in other cases it is used let.

Guess you like

Origin blog.csdn.net/sunddy_x/article/details/125446901