zoukankan      html  css  js  c++  java
  • let和const====均参考阮大神的es6入门

     

    // 解构复制
    // let [foo,[[bar],baz]] = [1,[[2],3]];
    // console.log(foo);//1
    // console.log(bar);//2
    // console.log(baz);//3

     

    // let [,,third] = ["foo","bar","baz"];
    // console.log(third)//baz;

     

    // let [x,,y] = [1,2,3];
    // console.log(x+"---"+y)//1---3

     

    // let [head,...tail] = [1,2,3,4];
    // console.log(Array.isArray(tail))//证明是数组
    // console.log(head+"--"+tail)//1--2,3,4
    // console.log(typeof tail)//object

     

    // let [x, y, ...z] = ['a'];
    // 解构不成功,变量的值就等于undefined
    // console.log(x+"---"+y+"---"+z)//a---undefined---[]

     

    // 如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错。
    // 报错
    // let [foo] = 1;
    // let [foo] = false;
    // let [foo] = NaN;
    // let [foo] = undefined;
    // let [foo] = null;
    // let [foo] = {};

     

    // 只要某种数据结构具有Iterator(迭代)接口,都可以采用数组形式的解构赋值。
    // Generator函数(生产者?)
    // function* fibs() {
    // var a = 0;
    // var b = 1;
    // while (true) {
    // //0 1 1 2 3 5
    // yield a;
    // //1,1 1,2 2,3 3,5 5,8
    // [a, b] = [b, a + b];
    // }
    // }

     

    // var [first, second, third, fourth, fifth, sixth] = fibs();
    // console.log(first)//0
    // console.log(second)//1
    // console.log(third)//1
    // console.log(fourth)//2
    // console.log(fifth)//3
    // console.log(sixth)//5

     

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

     

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

     

    // let不像var那样会发生“变量提升”现象。所以,变量一定要在声明后使用,否则报错。
    // console.log(foo); // 输出undefined
    // //console.log(bar); // 报错ReferenceError

     

    // var foo = 2;
    // //let bar = 2;// 报错ReferenceError

     

    // 只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
    // var tmp = 123;
    // 存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。
    // if (true) {
    // tmp = 'abc'; // ReferenceError
    // let tmp;
    // }

     

    // var tmp = 123;
    // if (true) {
    // let tmp;
    // tmp = 'abc'; //不报错
    // }
    // ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

     

    // 在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称TDZ)。
    // if (true) {
    // // TDZ开始
    // //tmp = 'abc'; // ReferenceError
    // //console.log(tmp); // ReferenceError

     

    // let tmp; // TDZ结束
    // console.log(tmp); // undefined

     

    // tmp = 123;
    // console.log(tmp); // 123
    // }

     

    // “暂时性死区”也意味着typeof不再是一个百分之百安全的操作。
    // typeof x; // ReferenceError
    // let x

     

    // 作为比较,如果一个变量根本没有被声明,使用typeof反而不会报错。
    //console.log(typeof y)//undefined

     

    // 调用bar函数之所以报错(某些实现可能不报错),是因为参数x默认值等于另一个参数y,而此时y还没有声明,属于”死区“。如果y的默认值是x,就不会报错,因为此时x已经声明了。
    // function bar(x = y, y = 2) {
    // return [x, y];
    // }

     

    // bar(); // 报错

     

    // function bar(y = x, y = 2) {
    // return [x, y];
    // }

     

    // bar(); // 报错

     

    // function bar(x = 2, y = x) {
    // return [x, y];
    // }
    // bar(); // [2, 2]

     

    // 暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。

     


    // 不允许重复声明
    // 报错
    // function () {
    // let a = 10;
    // var a = 1;
    // }

     

    // // 报错
    // function () {
    // let a = 10;
    // let a = 1;
    // }

     

    // function func(arg) {
    // let arg; // 报错
    // }

     

    // function func(arg) {
    // {
    // let arg; // 不报错
    // }
    // }

     


    // 变量提升
    // ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。

     

    // 第一种场景,内层变量可能会覆盖外层变量。
    // var tmp = new Date();

     

    // function f() {
    // console.log(tmp);
    // if (false) {
    // var tmp = "hello world";
    // }
    // }

     

    // f(); // undefined

     

    // var tmp = new Date();

     

    // function f() {
    // console.log(tmp);
    // if (true) {
    // var tmp = "hello world";
    // }
    // }

     

    // f(); // undefined
    // 上面代码中,函数f执行后,输出结果为undefined,原因在于变量提升,导致内层的tmp变量覆盖了外层的tmp变量。
    // 第二种场景,用来计数的循环变量泄露为全局变量
    // var s = 'hello';
    // for (var i = 0; i < s.length; i++) {
    // console.log(s[i]);
    // }

     

    // console.log(i); // 5

     

    // var s = 'hello';
    // for (let i = 0; i < s.length; i++) {
    // console.log(s[i]);
    // }
    // console.log(i); // i is not defined

     

    // 这表示外层代码块不受内层代码块的影响
    // function f1() {
    // let n = 5;
    // if (true) {
    // let n = 10;
    // }
    // console.log(n); // 5
    // }
    // f1()//5

     


    // 互不影响
    // {{{{
    // let insane = 'Hello World';
    // {let insane = 'Hello';
    // console.log(insane)//Hello
    // }
    // console.log(insane)//Hello World
    // }}}};

     

    // 块级作用域的出现,实际上使得获得广泛应用的立即执行匿名函数(IIFE)不再必要了。
    // IIFE写法
    // (function () {
    // var tmp = ...;
    // ...
    // }());

     

    // // 块级作用域写法
    // {
    // let tmp = ...;
    // ...
    // }

     

    // ES5严格模式
    // 'use strict';
    // if (true) {
    // function f() {}
    // }
    // 报错

     

    // ES6严格模式
    // 'use strict';
    // if (true) {
    // function f() {}
    // }
    // 不报错

     

    // 报错
    // function f() { console.log('I am outside!'); }
    // (function () {
    // if (false) {
    // // 重复声明一次函数f
    // function f() { console.log('I am inside!'); }
    // }

     

    // f();
    // }());

     

    // ES6的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。
    // 'use strict';
    // if (true) {
    // function f() {}
    // }

     

    // // 报错
    // 'use strict';
    // if (true)
    // function f() {}

     

    // const声明一个只读的常量。一旦声明,常量的值就不能改变。
    // const foo = {};
    // foo.prop = 123;

     

    // foo.prop
    // 123

     

    //foo = {}; // TypeError: "foo" is read-only

     

    // 常量foo储存的是一个地址,这个地址指向一个对象。不可变的只是这个地址,即不能把foo指向另一个地址,但对象本身是可变的,所以依然可以为其添加新属性。

     

    // const a = [];
    // a.push('Hello'); // 可执行
    // a.length = 0; // 可执行
    // a = ['Dave']; // 报错

     

    // 如果真的想将对象冻结,应该使用Object.freeze方法
    // const foo = Object.freeze({});

     

    // // 常规模式时,下面一行不起作用;
    // // 严格模式时,该行会报错
    // foo.prop = 123;
    // 常量foo指向一个冻结的对象,所以添加新属性不起作用,严格模式时还会报错。

     

    // ES6为了改变这一点,一方面规定,为了保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从ES6开始,全局变量将逐步与顶层对象的属性脱钩。

     

    // var a = 1;
    // // 如果在Node的REPL环境,可以写成global.a
    // // 或者采用通用方法,写成this.a
    // window.a // 1

     

    // let b = 1;
    // window.b // undefined

     

  • 相关阅读:
    Python 递归函数详解
    CentOS7 删除virbr0虚拟网卡
    /usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:245: running exec setns .....
    Linux系统添加永久静态路由的方法(包含Centos7)
    正则表达式
    Unity3D -- shader语法内置函数
    Unity3D -- shader光照常用函数和变量
    Unity3D -- shader常用函数和变量
    Unity 着色器训练营(2)
    Unity Shader着色器优化
  • 原文地址:https://www.cnblogs.com/mr-pz/p/5982925.html
Copyright © 2011-2022 走看看