变量声明

  • html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>变量声明</title>
        <script src="blsm.js"></script>
    </head>
    <body>
    </body>
</html>
  • ts

/**
 * var:之前的javascript只能通过var进行变量声明,而var声明的变量有很多缺陷
 * 作用域规则:
 * 1 外部可访问到内部定义的变量
 * 2 变量可以在未定义的时候使用,只是值为undefined
 *   var声明可以在包含它的函数,模块,命名空间或全局作用域内部任何位置被访问
 * 3 捕获变量的怪异之处
 */
//var 1
function f10(shouldInitialize: boolean) {
    if (shouldInitialize) {
        var x = 10;
    }
    return x;//这里没有问题,不会报错
}
console.log(f10(true));//10;
console.log(f10(false));//undefined;

//var 2
console.log('blsmname:'+blsm_name);
var blsm_name = "jack";
//let则不行
// console.log(name2);//报错:因为下面用let声明了该变量,那么声明之前的就属于暂时性死区
// let name2='jack';

//var 3
// for (var i = 0; i < 10; i++) {
//     setTimeout(function() { console.log(i); }, 100 * i);
// }
//结果:10个10
//var替换为let,结果为0-9
// for (let i = 0; i < 10; i++) {
//     setTimeout(function() { console.log(i); }, 100 * i);
//     console.log(i);
// }
/*
 * 原因分析:
 * 1 每一次for循环的时候,settimeout都执行一次,但是里面的函数没有被执行,
 *   而是(里面的函数)被放到了任务队列里面,当主线程执行完成后,才进入任务队列里面执行,
 * 2 任务队列可分为宏任务(macro-task)和微任务(micro-task)。主线程执行完之后->执行微任务->执行宏任务(在执行某个宏任务时这个宏任务就可以当做主线程,所以和前面的顺序一样)
 *   XHR回调、事件回调(鼠标键盘事件)、setImmediate、setTimeout、setInterval、indexedDB数据库操作等I/O都属于宏任务
 *   process.nextTick、Promise.then、Object.observer(已经被废弃)、MutationObserver(html5新特性),Promise.then属于微任务
 * 3 因此setTimeout的函数则会被放到任务队列中,普通代码(console.log(i))会按照主线程执行
 * 4 主线已经执行完毕,所以对于var定义的变量来说,现在的i已经==10,因此输出10个10
 * 5 对于let定义的变量来说:
 *   for循环头部的let 声明还会有一个特殊的行为。
 *   这个行为指出变量在循环过程中不止被声明一次,每次迭代都会声明,
 *   随后的每个迭代都会使用上一个迭代结束时的值来初始化这个变量,
 *   因此,每个迭代都会声明变量,后面在function() { console.log(i); }执行的时候的i是每次迭代时所声明的,
 *   最终得到值为0-9
 */

function ff10([first, second]:[number,number]) {
    console.log(first);
    console.log(second);
}
let input = [1, 2];
//ff(input);//这里报错只是语法报错,其实是可以这么用的,输出的结果没问题

let input2:[number,number] = [1,2];
// let [name3,age3]:[string,number] = input3;//这么定义变量是错误,变量不能是[...],都不符合变量命名规范了


//解构:
//数组解构
//1.1
let params = [1,2];
// params = [];
let [p0=100,p1]:number[] = params;//OK:可以去掉':number[]',可以使用默认值
// let [p0,p1]:[number,number] = params;//error
console.log(p0,p1);

//1.2 对于已定义的参数,可以通过解构来交换
let min = 0;
let max = 100;
console.log(min,max);//0,100
[min,max] = [max,min];
console.log(min,max);//100,0

//1.3 作为函数参数
function func([num1,num2]){
    console.log(num1,num2);
}
func([2,3]);

//...:剩余的都匹配到other:[3,4,5]
params = [1,2,3,4,5];
let [first,second,...other] = params;
console.log(first,second,other);

//这样只会匹配第一个数:1
[first] = params;
console.log(first);

//或者可以匹配某几个元素
let [,two,,four,] = params;
console.log(two,four);


//对象解构
let json = {
    myName:'liucai',
    age:24,
    sex:'man'
}
//let定义的变量名要和Json里的一样(但如果是这样:let {myName:n,age:a},这里后面是n,a都没关系,实际上是要前面的属性名对应一致)
let {myName,age} = json;//多的sex没关系
console.log(myName,age);

//利用()防止{}被当做代码块
let aa;
let bb;
({aa,bb} = {aa:'a',bb:'b'});//这里要用'()',否则直接用{}会被当做代码块,不会当做解构
console.log(aa,bb);

//...剩余变量
let o = {
    a: "foo",
    b: 12,
    c: "bar"
};
let {a:string,...otherParam} = o;//这个地方a要指定类型,otherParam对应后面的b,c

//属性重命名:a和b对应o对象里面的属性名,然后定义的变量的名字是newName1和newName2
//也就相当于:let newName1 = o.a;let newName2 = o.b;
let { a: newName1, b: newName2 } = o;

//给变量指定类型
let json2 = {
    j1:'jjj',
    j2:222
}
let {j1,j2}:{j1:string,j2:number} = json2;
console.log(j1,j2);

//默认值
let json3 = {
    xx:10,
    yy:20
}
let {xx=0,yy=100} = json3;//如果json没值(如let json3;),则为默认值,注:let json3 = {x:10,y:20},这样不行,这里会报错,因为找不到xx,yy属性
console.log(xx,yy);


//展开操作符
//1 展开数组
let bofore = [1,2,3,4,5];
let after = [6,7,8,9,10];
let num = [0,...bofore,...after];
console.log(num);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

//展开对象
let jsonObj = {
    name:'wanglin',
    age:1423346,
    height:222
}
let newJson = {name:'suming',...jsonObj};
console.log(newJson);//{name: "wanglin", age: 1423346, height: 222}--前面的name属性值会被后面的覆盖掉

//使用...展开class时,会丢失方法
class C {
    constructor(){
    }
    name:string = 'CCC';
    showName(){
        console.log(this.name);
    }
}
let newC = new C();
console.log(newC.name);
newC.showName();
let newCC = {...newC};//对构造的class对象进行解构
console.log(newCC.name);//调用不到showName()方法了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值