接着上篇继续写。

不定参数

转载请注明来源: http://blog.csdn.net/caoshiying非法转载或抄袭将委托CSDN追究法律责任。
不定参数是在函数中使用命名参数同时接收不定数量的未命名参数。这只是一种语法糖,在以前的JavaScript代码中我们可以通过arguments变量来达到这一目的。不定参数的格式是三个句点后跟代表所有不定参数的变量名。比如下面这个例子中,…x代表了所有传入add函数的参数。

function add(...x){
    return x.reduce((m,n)=>m+n);
}
console.log(add(1,2,3));
console.log(add(1,3,4,5));

拓展参数

拓展参数则是另一种形式的语法糖,它允许传递数组或者类数组直接做为函数的参数而不用通过apply。

var peoples=['Wayou','John','Sherlock'];
function printPeoples(people1,people2,people3){
    console.log(`Hello ${people1},${people2},${people3}`);
}
printPeoples (...people);
printPeoples.apply(null,peoples);

let与const 关键字

可以把let看成var,只是它定义的变量被限定在了特定范围内才能使用,而离开这个范围则无效。const则很直观,用来定义常量,即无法被更改值的变量。

for (let i=0;i<2;i++){
    console.log(i);
}
console.log(i);//输出:undefined,严格模式下会报错

for of 值遍历

我们都知道for in 循环用于遍历数组,类数组或对象,ES6中新引入的for of循环功能相似,不同的是每次循环它提供的不是序号而是值。示例工程:E10。

var arrays=['李婷',22,"羽毛球"];
    for(let v of arrays){
        printvariables(v);
    }
    for(let v in arrays){
        printvariables(arrays[v]);
    }

    function printvariables(v) {
        document.write(v);
        document.write("<br/>");
    }

生成器函数(Generator Function)

生成器函数与普通函数的语法区别很小,只是函数名称前面增加一个星号*。生成器函数不立即执行函数体,而是返回一个迭代器(iterator),等待用户调用迭代器的next方法。在迭代器函数内部可以应用yield等关键字。
生成器函数的行为与普通函数并不相同,表现为如下3点:
1. 通过new运算符或函数调用的形式调用生成器函数,均会返回一个生成器实例;
2. 通过new运算符或函数调用的形式调用生成器函数,均不会马上执行函数体的代码;
3. 必须调用生成器实例的next方法才会执行生成器函数体的代码。
这个特性单独应用的意义不大。
iterator是一个特殊对象,拥有一个next方法,这个方法返回一个对象{done,value},这个对象包含两个属性,一个布尔类型的done和包含任意值的value。iterable是一个特殊对象,拥有一个obj[@@iterator]方法,这个方法返回一个iterator。
generator是一种特殊的iterator。反的next方法可以接收一个参数并且返回值取决与它的构造函数(generator function)。generator同时拥有一个throw方法。生成器函数函数即generator的构造函数。此函数内可以使用yield关键字。在yield出现的地方可以通过generator的next或throw方法向外界传递值。
yield 关键字:它可以暂停函数的执行,随后可以再次进入函数继续执行。
示例工程:E11。

function writeMessage(msg) {
        document.write(msg);
        document.write("<br/>");
    }

    function *enumerable(msg) {
        writeMessage(msg);
        var msg1 = yield msg + " after ";
        writeMessage(msg1);
        var msg2 = yield msg1 + " after ";
        writeMessage(msg2);
        try {
            var msg3 = yield msg2 + " after ";
            writeMessage("OK");
        } catch (e) {
            writeMessage(e);
        }
        writeMessage(msg2 + " over ");
    }

    (function () {
        var iterator=enumerable("hello");
        var ret=iterator.next();
        ret=iterator.next("world");
        ret=iterator.next("game");
        ret=iterator.throw(new Error("test"));
        iterator=enumerable("hello");
        for(ret of iterator){
            writeMessage(JSON.stringify(ret));
        }
    })();

模块

在ES6标准中,JavaScript原生支持module了。这种将JS代码分割成不同功能的小块进行模块化的概念是在一些三方规范中流行起来的,比如Commonjs和AMD模式。
将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用。示例工程:E12。

module people from "/people.js";
import People from "people";

class Student extends People{
    constructor(name,age,hobby){
        super(name,age);
        this.hobby=hobby;
    }

    printSelf(){
        document.write(this.name);
        document.write("<br/>");
        document.write(this.age);
        document.write("<br/>");
        document.write(this.hobby);
        document.write("<br/>");
    }
}

(function () {
    var student=new Student("李婷","羽毛球");
    student.printSelf();
})();

以下是people.js的代码。

moudle "people"{
    export class People{
        constructor(name,age){
            this.name=name;
            this.age=age;
        }

        get name(){
            return this._name;
        }

        get age(){
            return this._age;
        }

        set name(name){
            this._name=name;
        }

        set age(age){
            this._age=age;
        }
    }
}

Map、Set

这些是新加的集合类型,提供了更加方便的获取属性值的方法,不用像以前一样用hasOwnProperty来检查某个属性是属于原型链上的呢还是当前对象的。同时,在进行属性值添加与获取时有专门的get,set 方法。示例工程:E13。这个工程是Node.js工程。

(function () {
    var s=new Set();
    s.add("Hello World!").add("你好,世界!").add("hola mundo!");
    console.log("集合中的元素个数是2吗?\t"+s.size===2);
    console.log("集合中有\"Hello World!\"这个关键词吗?\t"+s.has("Hello World!"));

    var m=new Map();
    m.set("hello",Math.random());
    m.set(s,Math.random());
    console.log(m.get(s));
})();

WeakMap、WeakSet

有时候我们会把对象作为一个对象的键用来存放属性值,普通集合类型比如简单对象会阻止垃圾回收器对这些作为属性键存在的对象的回收,有造成内存泄漏的危险。而WeakMap,WeakSet则更加安全些,这些作为属性键的对象如果没有别的变量在引用它们,则会被回收释放掉,具体还看下面的例子。示例工程:E14。

(function () {
    var ws=new WeakSet();
    var wm=new WeakMap();
    var student={
        name:"李婷",age:22
    };
    ws.add(student);
    wm.set(student,Math.random());
    console.log("因为添加到ws的这个临时对象没有其他变量引用它,所以ws不会保存它的值,也就是说这次添加其实没有意思。");
    console.log(wm.get(student));
    console.log(ws.size==undefined);
    console.log(wm.size==undefined);
})();

Proxy

Proxy可以监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操作。一下子让我们对一个对象有了很强的追踪能力,同时在数据绑定方面也很有用处。

(function () {
    var student={
        name:"李婷",mark:60
    };
    var interceptor={
        set(receiver,property,value) {
            console.log(property+ "属性的值变成了"+value);
            receiver[property]=value;
        }
    };
    student=new Proxy(student,interceptor);
    student.mark=100;
    student.name="你好!";
})();

上面代码我已加了注释,这里进一步解释。对于处理程序,是在被侦听的对象身上发生了相应事件之后,处理程序里面的方法就会被调用,上面例子中我们设置了set的处理函数,表明,如果我们侦听的对象的属性被更改,也就是被set了,那这个处理程序就会被调用,同时通过参数能够得知是哪个属性被更改,更改为了什么值。

覆盖

ES6仍然不支持类的重载与多态。子类的成员函数如果与父类成员函数相同则造成覆盖的现象。父类的方法并没消息,可通过super关键字调用。示例工程:E16。

class People{
    constructor(name,age){
        this.name=name;
        this.age=age;
    }

    printSelf(){
        console.log("姓名:"+this.name);
        console.log("年龄:"+this.age);
    }
}

class Student extends People{
    constructor(name,age);
        this.hobby=hobby;
    }

    printSelf(){
        super.printSelf();
        console.log("爱好:"+this.hobby);
    }
}

(function () {
    var student=new Student("李婷","羽毛球");
    student.printSelf();
})();

Symbols

我们知道对象其实是键值对的集合,而键通常来说是字符串。而现在除了字符串外,我们还可以用symbol这种值来做为对象的键。Symbol是一种基本类型,像数字,字符串还有布尔一样,它不是一个对象。Symbol 通过调用symbol函数产生,它接收一个可选的名字参数,该函数返回的symbol是唯一的。之后就可以用这个返回值做为对象的键了。Symbol还可以用来创建私有属性,外部无法直接访问由symbol做为键的属性值。示例工程:E17。

(function () {
    var key=Symbol("key");
    function StudentClass(name) {
        this[key]=name;
    }
    StudentClass.prototype={
        doStuff () {
            console.log(this[key]);
        }
    };
    var student=new StudentClass("李婷");
    console.log(student["key"]);
    student.doStuff();
})();

Math,Number,String,Object 的新API

对Math、Number、String还有Object等添加了许多新的API。对这些新API进行了简单展示。

Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false

Math.acosh(3) // 1.762747174039086
Math.hypot(3,4) // 5
Math.imul(Math.pow(2,32) - 1,Math.pow(2,32) - 2) // 2

"abcde".contains("cd") // true
"abc".repeat(3) // "abcabcabc"

Array.from(document.querySelectorAll('*')) // Returns a real Array
Array.of(1,3) // Similar to new Array(...),but without special one-arg behavior
[0,0,0].fill(7,1) // [0,7,7]
[1,3].findindex(x => x == 2) // 1
["a","b","c"].entries() // iterator [0,"a"],[1,"b"],[2,"c"]
["a","c"].keys() // iterator 0,1,2
["a","c"].values() // iterator "a","b","c"

Object.assign(Point,{ origin: new Point(0,0) })

Promises

Promises是处理异步操作的一种模式,之前在很多三方库中有实现,比如jQuery的deferred 对象。当你发起一个异步请求,并绑定了.when(),.done()等事件处理程序时,其实就是在应用promise模式。HTML5的Web Worker异曲同工,详情请看MDN。示例工程:E18。

/** * 目的:一个HTTP请求网络客户端 *    展示箭头函数、加强型对象字面量、类、内部类、回调、WeakMap等ES6特性的应用 *    展示NodeJS http模块、jsdom模块的应用 * 作者:岬淢箫声 * 邮箱:jiayuxiaosheng@foxmail.com * 日期:2016-10-15 */

var HttpClient = (function () {
    var weakMap=new WeakMap();
    var that={};
    class InnerHttpClient{
        constructor(url="www.epsg.org",userName="zhuangtaiqiusi@126.com",password="p.123456"){
            this.url=url;
            this.userName=userName;
            this.password=password;
            var privateProperties={
                compress:"unkNown",onSuccess(){},onFault(){},chunks:[],statusCode:100
            };
            weakMap.set(this,privateProperties);
            that=this;//Promise、NodeJS的http模块中的类等等都会改变上下文环境(Context),在Promise启动后用到本类方法时需要记住this
        }

        /** * 两个参数是回调函数,回调函数各都有1个参数 */
        loadHTML(onSuccess,onFault){
            weakMap.get(that).onSuccess=onSuccess;
            weakMap.get(that).onFault=onFault;
            var http = require('http');
            var authorization = "Basic" + new Buffer(that.userName + ":" + that.password).toString("base64");
            var options = {
                host: that.url,port: 80,path: "/",method: "GET",headers: {
                    "accept": "*/*",'content-type': "application/atom+xml",'accept-encoding': 'gzip,deflate','accept-language': 'en-US,en;q=0.9','authorization': authorization,'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/54.0.2840.59 Safari/537.36'
                }
            };
            var request = http.request(options,that.onRequest);
            request.on("error",that.onError);
            request.end();
        }

        onError(error){
            weakMap.get(that).onFault(error);
        }

        /** * this是ClientRequest * @param response 远端服务器响应的消息体 */
        onRequest(response){
            var equal = require('assert').equal;
            weakMap.get(that).statusCode=response.statusCode;
            console.log("状态码:" + response.statusCode);//响应消息头是一次性发送来的
            equal(response.statusCode,200);
            console.log("消息头:"+JSON.stringify(response.headers));
            weakMap.get(that).compress=response.headers["content-encoding"];
            response.on("data",that.onData);
            response.on("end",that.onEnd);
        }

        /** * this是IncomingMessage * @param chunk 用gzip压缩后的二进制流 */
        onData(chunk){
            weakMap.get(that).chunks.push(chunk);//响应消息体可能是分批发送的。
        }

        /** * this是IncomingMessage */
        onEnd(){
            var zlib = require('zlib');
            var buffer=Buffer.concat(weakMap.get(that).chunks);
            var compress=weakMap.get(that).compress;
            switch(compress){
                case "gzip":
                    zlib.gunzip(buffer,(err,decode)=>{
                        that.resolveHTML(decode.toString());
                    });
                    break;
                case "deflate":
                    zlib.inflate(buffer,decode)=>{
                        that.resolveHTML(decode.toString());
                    });
                    break;
                default:
                    that.resolveHTML(buffer.toString());
                    break;
            }
            weakMap.get(that).onSuccess(weakMap.get(that).statusCode);
        }

        resolveHTML(html){
            var jsdom=require('jsdom');
            console.log("正在解析网页中的所有锚链接。。。")
            jsdom.env(html,[],function (domerr,window) {
                var doms=window.document.getElementsByTagName("a");
                for(var i=0;i<doms.length;i++){
                    var innerHTML=doms[i].innerHTML.toString().trim();
                    if(!(innerHTML.contains("<")||innerHTML.contains("&"))){
                        if(doms[i].href==undefined){
                            console.log(innerHTML+"\t");
                        }else{
                            console.log(innerHTML+"\t"+doms[i].href);
                        }
                    }
                }
            });
        }

        start(){
            var promise = new Promise(this.loadHTML);
            promise.then(result => {
                console.log("成功了,代码是:" + result);
            },err=> {
                console.log("失败了,原因是:" + err);
            });
            console.log("任务进行中,请稍等。");
        }
    }
    return InnerHttpClient;
})();

(function () {
    String.prototype.contains = function (search) {
        return this.indexOf(search) != -1;
    };
    var client = new HttpClient();
    client.start();
})();

转载请注明来源: http://blog.csdn.net/caoshiying非法转载或抄袭将委托CSDN追究法律责任。

AngularJS系列之ES6特性二的更多相关文章

  1. 创建 Swift 自定义集合类

    在本文,你将学习用Swift的collection协议创建自定义集合类型。当文本结束,你会拥有一个强大的自定义集合类型,拥有Swift内置集合的所有功能。小于次的版本无法编译,因为Swift标准库发生了剧烈改变。在一个Set集合中,重复对象会被忽略。Swift提供了让Bag符合传统集合的所有工具。你需要先了解一下在Swift中,让一个对象变成集合需要做些什么。要理解什么是Swift集合,首先需要它继承的协议层次:Sequence协议表示类型支持排序、以迭代的方式访问其元素。

  2. swift – 使用依赖于元素类型的递归属性/方法扩展Collection

    –但调度已关闭:$1.flatCount不绑定到第二个递归版本,但总是绑定到第一个普通版本.也就是说,flatCount仅计算第一个嵌套级别.有没有办法以表达此功能的方式处理类型和/或调度?

  3. 数组 – Swift 2D数组通用扩展 – 访问第二维的问题

    我正在尝试将以下函数转换为2D数组的通用扩展.我特别难以指出如何指定约束以允许我访问第二个维度.这是一次失败的尝试:问题是编译器不知道你的扩展是用于2D数组–它只知道它是用于集合数组.因此,关联类型Indexdistance和Index不一定是Int.因此,解决方案是约束您的扩展,以便Element的Indexdistance和Index属于Int类型.这将允许您形成范围0..

  4. Android Studio是否支持用于Android UI设计的AngularJS?

    我对AndroidStudio有疑问:AS在设计XML文件时是否支持AngularJS代码,例如:对于小动画或效果?

  5. android – MarkerView走出图表的最后一点

    我正在使用MarkerView类在图表中显示标记视图.我创建的markerview布局包含两个textview,一个在另一个之下.我面临的问题是图表上最后一个点的标记视图是图表中的一半,而图表中的一半.下面的两张图片清楚地说明了问题:第一张图显示了图表中心点的标记视图,显示没有任何问题:第二个图像,如下所示,显示图表最后一个点的标记视图,它是图表中的一半.如何调整此标记视图以使其在图表区域内显示.Wiki不会为markerview声明任何自定义.还有更多自定义吗?

  6. android – 如何使用ClientID和ClientSecret在Phonegap中使用Angularjs登录Google OAuth2

    我正尝试使用Angularjs(使用IonicFramework)通过GoogleOAuth2从我的Phonegap应用程序登录.目前我正在使用http://phonegap-tips.com/articles/google-api-oauth-with-phonegaps-inappbrowser.html进行登录.但是当我使用Angular-UI-RouterforIonic时,它正在创建非常

  7. android – 当app是后台FCM时,如何检索通知消息intent.getExtras()

    我正在使用FCM进行简单通知当应用程序处于前台时,一切正常.我在onMessageReceived方法中收到通知和数据消息.但是当应用程序处于后台时,我会在系统托盘中收到通知.当我点击控件时,它会转到主要活动.当我解析intent.getExtras();时,我只得到这个关键数据–google.sent_time,from,google.message_id,collapse_key.如何从intent.getExtras()获取系统托盘中可见的通知消息标题和消息?

  8. Android – 使用ORMLite DAO作为ContentProvider

    我旁边的同事真的非常想使用Ormlite,因为他不想自己编写任何映射.我知道atleap和Android-OrmliteContentProvider项目的存在.这些只为活动提供了一个光标,我的同事希望拥有模型列表或单个模型.这可以实现吗?和Contentprovider必须使用模型.但是,使用列表等仍然可以实现相同的功能吗?将事件传递给contentobservers等活动?

  9. 如何在Android中轻击叠加层显示弹出窗口?

    在我的地图应用程序中,我在地图上显示一组叠加层.每当我点击叠加层,我需要显示一个弹出窗口,像这样任何人可以帮我解决这个问题吗?解决方法是的,您可以通过点按地图设计我们的自助信息窗口来显示信息,如果您明白,请重播我,我将向您提供代码.在这段代码中,我设计了一个绘制信息窗口的函数

  10. 利用require.js与angular搭建spa应用的方法实例

    这篇文章主要给大家介绍了关于利用require.js与angular搭建spa应用的方法实例,文中通过示例代码给大家介绍的非常详细,对大家的理解和学习具有一定的参考学习价值,需要的朋友们下面跟着小编来一起看看吧。

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部