zoukankan      html  css  js  c++  java
  • ES6新增—let、const、字符串连接、解构赋值、复制数组

    我们在下面的文章中具体讲解ES6时,使用Traceur转码器的直接插入网页的方法来转码ES6
    traceur:是由Google出的编译器,可以将ES6编译成ES5
    bootstrap:是一个引导程序(与响应式的bootstrap不同)
    需要将traceur.js和bootstrap.js下载下来,引入到当前文件中即可
    ---------------------------------------------------------------------
    注意:在使用ES6时,先不用引入任何东西,去测试,
    当不支持ES6时,再去引入traceur.js和bootstrap.js对RS6进行转码。
    以为现在浏览器已经支持部分ES6功能,有的不需要转码,转码反而错误

    1.let定义变量 ——已经被浏览器实现了,不需要编译
    以前定义变量:var a=12;
    ES6定义变量:let a=12;
    代码块:用{}包起来的代码,称为代码块,如if语句,for循环,while循环
    let和var定义变量的区别:
    1)let即具有函数作用域,又具有代码块作用域
    var只有函数作用域
    {
    let a=12;
    alert(a); //正常执行,弹出12
    }
    alert(a); //报错,a没有定义

    {
    var b=5;
    alert(b); //能正常输出
    }
    alert(b); //第二次也能够正常输出


    2)let不允许在相同作用域内,重复声明同一个变量。
    var定义的变量可以重复声明赋值,且后一次会把前一次的值给覆盖
    // 报错
    function () {
    let a = 10;
    var a = 1;
    }

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

    因此,不能在函数内部重新声明参数。
    function func(arg) {
    let arg; // 报错
    }

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

    var b=12;
    var b=5; //正常,后一次把前一次的给覆盖
    所以由上面的区别可以看出,let才更接近其他语言的变量

    3)var存在变量提升,即变量可以在声明之前使用,值为undefined
    let不存在变量提升,它所声明的变量一定要在声明后使用,否则报错
    // var 的情况
    console.log(foo); // 输出undefined
    var foo = 2;

    // let 的情况
    console.log(bar); // 报错ReferenceError
    let bar = 2;

    补充:
    1.在代码块内,使用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
    }
    2.只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
    var tmp = 123;
    if (true) {
    tmp = 'abc'; // ReferenceError
    let tmp;
    }


    let的应用:
    封闭空间:
    之前实现封闭空间的方法:
    (function(){
    var a=12; //这里的a相当于局部变量
    alert(a);
    })();
    现在使用let就相当于上面的封闭空间了,更加方便,清晰
    {
    let a=12;
    alert(a);
    }

    例如解决i的问题:
    window.onload=function(){
    var aBtn=document.getElementsByTagName('input');
    for(var i=0;i<aBtn.length;i++){
    aBtn.onclick=function(){
    alert(i); //这里并不会实现弹出0,1,2
    }
    }
    }

    window.onload=function(){
    var aBtn=document.getElementsByTagName('input');
    for(var i=0;i<aBtn.length;i++){
    (function(i){
    aBtn.onclick=function(){
    alert(i); //使用封闭空间进行解决,弹出0,1,2
    }
    })(i);
    }
    }

    window.onload=function(){
    var aBtn=document.getElementsByTagName('input');
    for(let i=0;i<aBtn.length;i++){
    aBtn.onclick=function(){
    alert(i); //使用let的块级作用域的特点,代替封闭空间
    }
    }
    }
    -----------------------------------------------------------------
    for循环中的i问题:
    下面的代码使用var,最后输出的是10。
    var a = [];
    for (var i = 0; i < 10; i++) {
    a[i] = function () {
    console.log(i);
    };
    }
    a[6](); // 10
    上面代码中,变量i是var声明的,在全局范围内都有效。所以每一次循环,新的i值都会覆盖旧值,导致最后输出的是最后一轮的i的值。

    如果使用let,声明的变量仅在块级作用域内有效,最后输出的是6。
    var a = [];
    for (let i = 0; i < 10; i++) {
    a[i] = function () {
    console.log(i);
    };
    }
    a[6](); // 6
    上面代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。

    另外,for循环还有一个特别之处,就是循环语句部分是一个父作用域,而循环体内部是一个单独的子作用域。
    for (let i = 0; i < 3; i++) {
    let i = 'abc';
    console.log(i);
    }
    // abc
    // abc
    // abc
    上面代码输出了3次abc,这表明函数内部的变量i和外部的变量i是分离的。


    总结:块级作用域其实就是匿名函数立即调用

    --------------------------------------------------------------------------------

    2.const定义常量
    特点:
    1)不能重复声明(一旦定义就不能修改),且定义时就要给初始值
    因为以后再也不能赋值了,所以声明的时候一定要有值
    const a=12;
    a=5; //报错,不能够修改
    const b;
    b=5; //报错,定义时就要给初始值
    用途:为了防止意外修改变量,比如引入库名,组件名等

    ---------------------------------------------------------------------------------

    3.字符串连接
    之前都是用+进行字符串连接:
    'abc'+变量名+'ef'

    var a='我们';
    var b='朋友';
    var str='大家在一起'+a+'都是好'+b;

    定义字符串的另外一种方法,使用反单引号
    var str=`` (又称为字符串模板)
    现在结合反单引号定义字符串,使用 ${变量名}进行连接 :
    `abc${变量名}ef`

    var a='我们';
    var b='朋友';
    var str=`大家在一起${a}都是好${b}`;

    ----------------------------------------------------------------------------

    4.解构赋值:
    var [a,b,c]=[12,2,43];

    与json配合使用:与顺序无关,前后名称要相同
    var{a,b,c}={a:12,b:5,c:16};
    var{a,b,c}={b:5,a:12,c:16};
    console.log(a);

    模式匹配:左右的模式要相同
    var [a,[c,d],b]=[12,[1,5],75];
    var [{a,e},[c,d],b]=[{e:'eee',a:'aaa'},[1,5],75];

    var arr=[{href:'abc',img:'12',src:'vnf'}];
    var [{href,img,src}]=arr;
    console.log(href);

    之前json做判断给默认值:
    var json={};
    var a=json.a||12;
    结构赋值给默认值:
    var {time=12,id=6}={};
    console.log(time,id);

    放到返回值里面:
    function getPos(){
    return {stop:12,left:14};
    }
    var {stop,left}=getPos;
    console.log(stop,left);

    ------------------------------------------------------------------------
    4.复制数组:
    方法1:循环
    var arr1=[1,2,3];
    var arr2=[];
    for(var i=0;i<arr1.length;i++){
    arr2.push(arr[i]);
    }

    方法2:Array.from(arr)
    var arr1=[1,2,3];
    var arr2=Array.from(arr1);

    方法3:ES6新增——var arr2=[...arr];
    var arr1=[1,2,3];
    var arr2=[...arr1]; //复制arr1

    [...]也可以与函数的传参结合在一起
    通常我们定义一个函数,参数用arguments来表示,arguments是一个数组,但又不完全具备数组的性质
    function show(arguments){
    console.log(arguments);
    //arguments.push(5); //这个是错误的,因为参数是由传进来的实参决定的
    }
    show(1,2,3,4);

    我们可以通过...来方便的将arguments转变成一个真正的数组
    function show(...args){
    console.log(args);
    args.push(5);
    console.log(args); //1,2,3,4,5
    }
    show(1,2,3,4);

  • 相关阅读:
    c++ builder 获取命令行参数
    c++ builder 只允许程序运行一个实例
    jQuery学习笔记(三)
    jQuery学习笔记(二)
    jQuery实现一个弹出登陆层的效果
    jQuery学习笔记(一)
    20117月
    201112学习
    21125
    211211
  • 原文地址:https://www.cnblogs.com/yufann/p/ES6-note2.html
Copyright © 2011-2022 走看看