let 箭头函数 参数增强 模板字符串 解构 class-1707

2017-08-21-day07


ES6:

1. let和块作用域
  • 问题1: hoist,打乱了程序的正常执行顺序

解决: 今后用let代替var声明变量
原理: let通过禁止在当前作用域内提前使用未声明的变量,来避免声明提前
强调: 如果已经用let声明的变量,不能再用var重复声明

<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <script>//hoist
    console.log(a);//报错!
        let a=10;//不提前,且之前不允许出现a
        console.log(a);//10

        var b=10;
        function fun(){//hoist
          console.log(b);//报错!
            let b=100;//不提前,且在当前作用域内的前半部分不允许提前出现b
            console.log(b);
        }
        fun();//报错
        console.log(b);
    </script>
 </body>
</html>
  • 问题2: js没有块级作用域, 块内的变量即使不执行,也会影响块外的变量:

块级作用域: 程序中的一对儿{}之间,称为代码块
js vs java: Java 三级作用域: 全局,函数,块
js 两级作用域: 全局,函数,没有块级作用
解决: 用let代替var
规定: let声明的变量仅在当前块内有效!
原理: 自动在块作用域位置创建匿名函数自调,划分临时作用域。

<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <script>
      var t=0;
        function conn(){
            t+=0.3; console.log("建立连接,耗时0.3s");
        }
        function query(){//hoist
            t+=0.8; console.log("查询数据,耗时0.8s");

            var err=false;
            if(err){//不执行!
                //(function(){
                let t=new Date();
                console.log("出错啦! at:"+t);
                //})();
            }
        }
        conn(); query();
        console.log("共耗时:"+t+"s");//1.1
    </script>
 </body>
</html>
  • 问题3: 原来在for/while/if...内声明的变量,出了结构,就不能使用

解决: 今后,凡是出了结构,还要使用的变量,必须在结构外提前声明。
总结: 今后所有变量都要用let声明,而不var

<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <button>click me!</button>
  <button>click me!</button>
  <button>click me!</button>
    <script>
        var btns=
            document.getElementsByTagName("button");
        for(let i=0;i<btns.length;i++){
            //(function(i){
                btns[i].onclick=function(){
                    alert(i);
                }
            //})(i);
//          btns[i].onclick=(function(){
//              var index=i;
//              return function(){
//                  alert(index);
//              }
//          })();
            //btns[0].onclick=function(){alert(index=0);}
            //btns[1].onclick=function(){alert(index=1);}
            //btns[2].onclick=function(){alert(index=2);}
        }//i=3
        //单击 3
        //单击 3
        //单击 3
    </script>
 </body>
</html>


<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <script>
        let sum=0;
        for(let i=1/*,sum=0*/;i<=100;sum+=i++);
        console.log(sum);//报错! 5050
    </script>
 </body>
</html>
2. 箭头函数: 简化回调函数

何时: 今后所有回调函数都可用箭头函数简化!
如何:

  1. 去function改箭头
    更简化:
  2. 如果只有一个参数变量,可省略()
  3. 如果函数体只有一句话,可省略{}
    如果仅有一句return,则可省略return
    箭头函数特点: 内容this通用!
<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <script>
        var arr=[23,2,12,3,123,1];
        arr.sort(//去function,改=>
            (a,b)=>a-b//如果只有一句话,可省略{}
        );            //如果只有一句return,可省略return
        console.log(String(arr));

        var arr=[1,2,3,4,5];
        arr.forEach(
            (val,i,arr)=>arr[i]=val*2
        );
        console.log(String(arr));

        var arr=[1,2,3,4,5];
        var evens=arr.map(
            val=>val*2//如果只有一个参数变量,可省略()
        );
        console.log(String(arr));
        console.log(String(evens));
    </script>
 </body>
</html>

箭头函数this

<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <script>
        var bob={
            sname:"Bob",
            friends:["jack","rose","tom","jerry","lucy"],
            intr(){
                this.friends.forEach(
                    val=>console.log(this.sname+" 认识 "+val)
//                  function(val){
//                      console.log(this.sname+" 认识 "+val);
//                  }.bind(this)
                );
            }
        }
        bob.intr();//intr中的this->bob
    </script>
 </body>
</html>
3.参数增强:

Default:(默认值)
function fun(参数1,参数2,参数3=默认值,参数4=默认值){}
调用时,如果传给参数的值有效,就用传入的值
如果没有传入参数,或传入的参数无效,则用提前指定的默认值

<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <script>
        function indexOf(arr,val,fromi=0){
            //fromi=fromi||0;
            for(var i=fromi;i<arr.length;i++){
                if(arr[i]===val) return i;
            }
            return -1;
        }
        var arr=[1,2,3,4,3,2,1];
              // 0 1 2 3 4 5 6
        console.log(
            indexOf(arr,2),  //1
            indexOf(arr,2,3),//5
            indexOf(arr,5),  //-1
            indexOf(arr,4,4) //-1
        );
    </script>
 </body>
</html>

REST:(剩余参数列表) 为了代替arguments

arguments的问题:
1. 不是真正的数组类型,无法使用数组类型的API
2. 默认只能获得所有参数值,无法仅选取部分参数值

解决: REST
何时: 今后,都是用REST语法代替arguments
如何:

      定义函数: function fun(参数1,参数2,...剩余参数的统称)
      调用时: ...剩余参数的统称 会获得一个数组

SPREAD:(散播) 为了代替apply打散数组类型的参数

apply的问题:
1. 必须传入第一个对象参数,代替this
2. 必须将所有参数都放入数组中

解决: spread
何时: 今后只要打散数组类型参数时,首选spread
如何: 定义函数时,参数变量是分开定义的
调用函数时,可用fun(值1,...arr),打散arr数组

以下是一个REST和spread的完整例子

<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <script>
        //REST: 代替arguments,聚拢多个参数值
        function calc1(ename,...sals){
            //sals:[10000,500,200,300]
            console.log(ename+"的总工资是"+
                sals.reduce((prev,val)=>prev+val)
            );
        }
        calc1("Li Lei",10000,500,200,300);
        calc1("Han Meimei",3000,4000,5000);
        
        function calc2(base,b1,b2,b3){//要求参数分别传入
            console.log(base+b1+b2+b3);
        }
        //SPREAD:代替apply
        //将数组打散为单个参数值,再分发给每个参数变量
        var bonus=[1000,2000,3000];//参数值在一个数组中
        calc2(10000,...bonus);

        var arr=[3,5,2];
        //Math.max.apply(null,arr)
        console.log(Math.max(...arr));
    </script>
 </body>
</html>
4. 模板字符串: 简化复杂格式的字符串拼接

何时: 今后所有字符串拼接,都用模板字符串代替+
如何:

  1. 用反引号`包裹整个字符串
  2. 在模板字符串内,自动支持换行
  3. 在模板字符串内,支持动态生成表达式的值
    要执行的表达式,必须用${}包裹
<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <script>
        var price=10,count=5;
        console.log(
                      `单价:¥${price.toFixed(2)}
                       数量:${count}
                       ============
                       总价:¥${(price*count).toFixed(2)}`
        );

        console.log(  
            String.raw `c:\windows\temp\new folder\index.html`
        );
    </script>
 </body>
</html>
5. 解构: 简化复杂对象的打散和批量赋值
  1. 数组解构: 等号左右两边都是数组格式; 解构时,用下标对应值和变量
  2. 对象解构: 等号左右两边都是对象格式; 解构时,用属性名匹配值和变量
  3. 参数解构: 在调用函数时,如果传入的参数值是数组或对象,也可被解构为单个参数值
//数组解构
var scores = [81, 59, 89];
var [math, chs, eng] = scores;
console.log(math, chs, eng);//81 58 89

//对象解构
var fbb = {
  math: 81,
  chs: 59,
  eng: 89
};
var {
  math: a,
  chs: b,
  eng: c
} = fbb;
console.log(a, b, c);//81 59 89

//数组参数解构
function sum1([math, chs, eng]) {
  return math + chs + eng
};
var scores = [81, 59, 89];
console.log(sum1(scores));//229

//对象参数解构
function sum2({
  math,//math:math,
  chs,//chs:chs,
  eng,//eng:eng
}) {
  return math + chs + eng
}
var fbb = {
  math: 81,
  chs: 59,
  eng: 89
};
console.log(sum2(fbb)) //229
6: class: 为了简化面向对象:

封装,继承,多态,访问器属性,静态方法
class: 集中定义构造函数和原型对象方法的程序结构
为什么: 更像封装
何时: 只要创建一种新类型,必须先定义class
如何:

class 类型名{
          constructor(...){
            this.xxx=xxx;
          }
          原型对象方法(){//类型名.prototype.xxx()
            ... this.xxx ...
          }
        }

继承: 2步:
1. 子类型构造函数中借用父类型构造函数:
super(参数值)
super自动指代父类型的构造函数
2. 让子类型继承父类型
class 子类型 extends 父类型
不用再Object.setPrototypeOf
访问器属性:

    class 类型名{
      constructor(...){
        this._age=age
      }
      get age(){return this._age}
      set age(val){
        ... ...
      }
    }

以下是一个例子

<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <script>
        class Flyer{
            constructor(fname,speed){
                //this->window->call->new
                this.fname=fname;
                this.speed=speed;
            }
            fly(){//Flyer.prototype.fly
                console.log(
                    this.fname+"以时速"+this.speed+"飞行");
            }
        }
        class Plane extends Flyer{
            constructor(fname,speed,score){
                super(fname,speed);
                this.score=score;
            }
            getScore(){
                console.log(
                    "击落"+this.fname+"得"+this.score+"分");
            }
        }
        
        var f16=new Plane("F16",1000,10);
        console.dir(f16);
        f16.fly(); f16.getScore();
    </script>
 </body>
</html>

getter setter例子

<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <script>
        class Emp{
            constructor(id,ename,age){
                this.id=id;
                this.ename=ename;
                Object.defineProperty(this,"_age",{
                    value:null,
                    writable:true
                })
                this.age=age;

                Object.seal(this);
            }
            get age(){return this._age}
            set age(val){
                if(val>=18&&val<=65)
                  this._age=val;
                else 
                  throw new RangeError(
                        "年龄必须介于18~65之间")
            }
        }

        var eric=new Emp(1001,"Eric",25);
        console.dir(eric);
        eric.age=26;
        console.log(eric.age)
        eric.age=-2;
    </script>
 </body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,093评论 0 13
  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,341评论 0 5
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,707评论 2 9
  • 白马非马 我自手书# 如果再无结果,放过他也放过自己。 这句话写在开头,说给大家、也说给我自己听。 其实姑娘们都是...
    萌面大瞎阅读 241评论 0 0
  • Have you ever show your respect to your professor or the ...
    张艾良阅读 235评论 0 3