文档章节

ES6中箭头函数,var,class详解

lemonzoey
 lemonzoey
发布于 2017/08/28 16:16
字数 2510
阅读 7
收藏 0

一,箭头函数和普通函数的区别

箭头函数简介:箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式第一种,省略{}和rerurn。第二种可以包含多条语句,这时候就不能省略{ ... }和return,如果参数不是一个,就需要用括号()括起来:

//第一种
 x => x * x
//第二种
x => {
    if (x > 0) {
        return x * x;
    }
    else {
        return - x * x;
    }
}

等同于

//第一种
function (x){
return x*x
}
//第二种
function (x){
    if(x)>0{
        return  x*x
        }
      else{
        return  -x*x
        }
}

区别:

1、首先箭头函数作为匿名函数,是不能作为构造函数的,不能使用new

2、this,普通函数构造函数的 this 指向了一个新的对象;如果函数是作为对象的方法被调用的,则其 this 指向了那个调用它的对象;但是箭头函数的则会捕获其所在上下文的 this 值,作为自己的 this 值。在使用call或apply绑定时,相当于只是传入了参数,对this没有影响

3、箭头函数不绑定arguments,取而代之用rest参数…解决

4、箭头函数当方法使用的时候没有定义this绑定

var obj = {
  i: 10,
  a: () => console.log(this.i, this),
  b: function() {
    console.log( this.i, this)
  }
}
obj.a(); //undefined, Window
obj.b(); // 10, Object {...}

5、箭头函数不能当做Generator函数,不能使用yield关键字

6、不能简单返回对象字面量

7、箭头函数不能换行

二.用户上传图片,图片存储的地址

图片保存在服务器上,数据库存储的是图片的链接地址,数据库是不会真的把一个文件存进去的 他只是把这个文件存储的地址保存起来

三.let,var 的区别

1.var的作用于是函数作用于,而let是块级别(大括号括起来的内容),for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

for (let i = 0; i < 3; i++) {
  let i = 'abc';
  console.log(i);
}
// abc
// abc
// abc

2.不存在变量提升,let所声明的变量一定要在声明后使用,否则报错。

// var 的情况
console.log(lemon); // undefined
var lemon= 1;

// let 的情况
console.log(zoey); // 报错
let zoey= 1;

3.暂时性死区

es6中规定,区域块中存在let和const命令,这个区块对这些命令声明的变量,最开始就是一个封闭的作用域,在申明之前就使用这些变量就报错,在let命令声明变量之前使用该变量都是不可以的。

var a = 1;
if(2>1){
    a = 3,//报错
    let a 
}

还有一些暂时性死区隐藏得比较深比如下面代码

//第一种
function sum(x=y,y=1){
    return [x,y]
}
sum()//报错,因为x=y时,y还没有赋值
//但是这样就没毛病
function sum(x=1,y=x){
    return [x,y]
}
sum()//[1,1]

//第二种
var x = x//不报错
    console.log(x);//undefined

let x = x;//报错:x is not defined

4.不允许重复声明

 // 报错
    function fn() {
        let a = 1;
        let a = 2;//Identifier 'a' has already been declared
    }
    fn()

 // 报错
    function fn1() {
        let a = 1;
        var a = 2;//Identifier 'a' has already been declared
    }
    fn1()

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

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

5.let实际上为 JavaScript 新增了块级作用域

  • ES6 允许块级作用域的任意嵌套,内层作用域可以定义外层作用域的同名变量。
  • ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。
  • ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。

四.利用generator完成fibnaqi数列

1.什么是generator

Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。

整个 Generator 函数就是一个封装的异步任务,或者说是异步任务的容器。异步操作需要暂停的地方,都用yield语句注明。

在 ES6 中定义一个生成器函数很简单,在 function 后跟上「*」即可:

function* foo1() { };
function *foo2() { };
function * foo3() { };

foo1.toString(); // "function* foo1() { }"
foo2.toString(); // "function* foo2() { }"
foo3.toString(); // "function* foo3() { }"
foo1.constructor; // function GeneratorFunction() { [native code] }

调用生成器函数会产生一个生成器(generator)。生成器拥有的最重要的方法是 next(),用来迭代:

function* foo() { };
var bar = foo();
bar.next(); // Object {value: undefined, done: true}

上面第 2 行的语句看上去是函数调用,但这时候函数代码并没有执行;一直要等到第 3 行调用 next 方法才会执行。next 方法返回一个拥有 value 和 done 两个字段的对象。

生成器函数通常和 yield 关键字同时使用。函数执行到每个 yield 时都会中断并返回 yield 的右值(通过 next 方法返回对象中的 value 字段)。下次调用 next,函数会从 yield 的下一个语句继续执行。等到整个函数执行完,next 方法返回的 done 字段会变成 true。下面看一个简单的例子:

function* list() {
    for(var i = 0; i < arguments.length; i++) {
        yield arguments[i];
    }
    return "done.";
}

var o = list(1, 2, 3);
o.next(); // Object {value: 1, done: false}
o.next(); // Object {value: 2, done: false}
o.next(); // Object {value: 3, done: false}
o.next(); // Object {value: "done.", done: true}
o.next(); // Error: Generator has already finished

每次调用 next 方法,都会得到当前 yield 的值。函数执行完之后,再调用 next 方法会产生异常。

 function* gen(x) {
        var y = yield x + 2;
        return y;
    }

    var g = gen(1);
    console.log(g.next()); // { value: 3, done: false }
    console.log(g.next()); // { value: undefined, done: true }

上面代码中,调用 Generator 函数,会返回一个内部指针(即遍历器)g。这是 Generator 函数不同于普通函数的另一个地方,即执行它不会返回结果,返回的是指针对象。调用指针g的next方法,会移动内部指针(即执行异步任务的第一段),指向第一个遇到的yield语句,上例是执行到x + 2为止。

换言之,next方法的作用是分阶段执行Generator函数。每次调用next方法,会返回一个对象,表示当前阶段的信息(value属性和done属性)。value属性是yield语句后面表达式的值,表示当前阶段的值;done属性是一个布尔值,表示 Generator 函数是否执行完毕,即是否还有下一个阶段。

2.用generater完成fibnaqi数列

function* fab(max) {
    var count = 0, last = 0, current = 1;

    while(max > count++) {
        yield current;
        var tmp = current;
        current += last;
        last = tmp;
    }
}

var o = fab(10), ret, result = [];

while(!(ret = o.next()).done) {
    result.push(ret.value);
}

console.log(result); // [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

ES6 也规定了类似的语法「for ... of」用来迭代

function fab(max) {
    var count = 0, last = 0, current = 1;

    while(count++ < max) {
        yield current;
        var tmp = current;
        current += last;
        last = tmp;
    }
}

for(var i of fab(10)) {
    console.log(i);
}

五.ES6 中class

1.定义

ES6提出了类(Class)的概念,让对象的原型的写法更像面向对象语言写法。 ES6中通过class定义对象,默认具有constructor方法和自定义方法。ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已.

  • 类的数据类型就是函数,类本身就指向构造函数。使用的时候,也是直接对类使用new命令,跟构造函数的用法完全一致。
  • 类和模块的内部,默认就是严格模式

2.基本语法

function Point (x,y){
            this.x=x;
        this.y=y;
        }
        Point.prototype.toString= function(){
            return this.x+this.y;
        }

注意:constructor方法对应ES5的构造函数;创建类的方法不需要使用function关键字,方法之间不需要逗号分隔。

ES5中定义对象时组合使用构造函数模式和原型模式,构造函数模式用于定义实例属性,原型模式用于定义共享方法和共享属性,节省内存,而且支持向构造函数传递参数。

        function Point (x,y){
            this.x=x;
        this.y=y;
        }
        Point.prototype.toString= function(){
            return this.x+this.y;
        }

构造函数的原型(prototype)属性在ES6中依旧存在,这一点和ES5一样:类的方法都定义在类的原型(prototype)上,在类的实例上面调用方法,其实就是调用原型上的方法。

    //实例的constructor方法就是类的原型(prototype)的constructor方法
    class B{
      constructor(){}
    }
    let b = new B();
    console.log(b.constructor === B.prototype.constructor);//true   

3.ES6 Class的继承

Class通过extends关键字实现继承

class ColorPoint extends Point{}

子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。

    class ColorPoint extends Point {
      constructor(x, y, color) {
        super(x, y); // 调用父类的constructor(x, y)
        this.color = color;
      }
      toString() {
        return this.color + ' ' + super.toString(); // super代表父类原型,调用父类的toString()
      }
    }

上面代码中,constructor方法和toString方法之中,都出现了super关键字,它在这里表示父类的构造函数,用来新建父类的this对象。

super这个关键字,既可以当作函数使用,也可以当作对象使用。第一种情况,super作为函数调用时,代表父类的构造函数,只能用在子类的构造函数中。ES6 要求,子类的构造函数必须执行一次super函数。第二种情况,super作为对象时,指代父类的原型对象。

如果子类没有定义constructor方法,这个方法会被默认添加。在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,是基于对父类实例加工,只有super方法才能返回父类实例。

        class Point {
          constructor(x, y) {
            this.x = x;
            this.y = y;
          }
        }
        
        class ColorPoint extends Point {
          constructor(x, y, color) {
            this.color = color; // ReferenceError
            super(x, y);
            this.color = color; // 正确
          }
        }

六.egg框架学习

© 著作权归作者所有

共有 人打赏支持
lemonzoey
粉丝 0
博文 11
码字总数 54195
作品 0
ES6中常用的10个新特性讲解

ECMAScript 6(ES6) 目前基本成为业界标准,它的普及速度比 ES5 要快很多,主要原因是现代浏览器对 ES6 的支持相当迅速,尤其是 Chrome 和 Firefox 浏览器,已经支持 ES6 中绝大多数的特性。 ...

木亦Sam
06/10
0
0
ES6常用特性

1、什么是ECMAScript6?和JavaScript什么关系? 1.1 什么是ECMAScript6? 首先说一下什么是ECMA(European Computer Manufacturers Association)欧洲计算机制造商协会。 如果说ECMA是一种组...

方千竹
2017/12/15
0
0
快速了解ES6

ECMAScript6(简称ES6),是JavaScript的下一代标准,因为ES6是在2015年发布的,所以又称ECMAScript2015(ES6 === ECMAScript2015) 目前不是所有的浏览器都完全兼容ES6,但很多程序猿已经开始使...

阿振
2016/04/15
185
0
es6基本语法

ES6是javascript的下一个版本,也叫做ECMAScript 2015,相对于es5,es6添加了许多新的特性,语言语法更加规范了,es6的出现使javascript步入了编程语言的正规军行列里,很多公司都逐渐使用es6...

马大哈tt
2017/12/23
0
0
前端面试之ES6篇(高产似母猪)

这也是前端面试经常询问的问题,经常问你es6出现了哪些新的特性,平时又使用过那些。在编写此教程的时候,第一句话往往就是面试常常问到的地方,然后后面就是他的详细解释,面试要求的内容我...

B_Cornelius
07/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

DES/3DES(TripleDES)加密、解密测试数据

以下结果经 PHP+openssl及VB.NET验证,ECB模式。 PHP 7.0.10 (cli) (built: Aug 18 2016 09:48:53) ( ZTS ) OpenSSL Library Version: OpenSSL 1.0.1t 3 May 2016 VB.net 2003 ****** DES(S......

SamXIAO
38分钟前
1
3
Java11的新特性

Java语言特性系列 Java5的新特性 Java6的新特性 Java7的新特性 Java8的新特性 Java9的新特性 Java10的新特性 Java11的新特性 Java12的新特性 序 本文主要讲述一下Java11的新特性 版本号 java...

go4it
39分钟前
3
0
Maven常用命令及相关笔记

Maven常用命令 dos指令 4. 编译源代码: mvn compile 6. 运行测试: mvn test 8. 打包: mvn package 9. 在本地Repository中安装jar: mvn install 10. 清除产生的项目: mvn clean 4. 运行项...

颖伙虫
45分钟前
1
0
swagger2.2.2 与 spring cloud feign冲突 导致服务请求报空

swagger2.2.2 与 spring cloud feign冲突 Java代码 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.choosefine.web.console.ar......

泉天下
48分钟前
1
0
设计模式之 明确责任 观察者模式 状态模式 责任链模式

观察者模式是任务分发的一种模式。 如果认为我们设计的系统的各个模块(或子系统)的最终目的是完成共同任务,那么这个任务如何分配到多个模块的就是我们遇到的第一个问题。简单设计场合我们...

backbye
53分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部