ES6 (js)

学习了很多vue的视频,还有nuxt的,还是不会。
还是要学ES6
本文的大部分出自小马老师的资料,还有曾大佬的文章

变量(Let 和 const)
在es6中,多用let 和const 来声明变量类型。因为var 会提前声明,也就是说,在spcrit标签中,每当检查到var 修饰的变量,就会把这个变量提前到scprit标签的第一行去自动声明后再用。这可能会导致var 变量的值出现变化。
例如:
输出结果是10,不是5
ES6 (js)_第1张图片
let 和const 的优点:
01.没有变量提升,像java代码顺序执行
02.是个块级变量,出了作用域就无法找到相关用let 或者 const修饰的变量
03.不能重复声明(这里是不允许在相同作用域内,此外,用const修饰的变量,不能重复赋值)

模块化字符串:就是用${变量名},来去获取变量

ES6 (js)_第2张图片

querySelector() 的用法:
querySelector() 方法仅仅返回匹配指定选择器的第一个元素。ES6 (js)_第3张图片
解构赋值:
解构赋值是对赋值运算符的一种扩展。它通常针对数组和对象进行操作。
01.数组解构(左边是声明的数组,右边也是一个数组)
之前的赋值类似于编程语句,就好像:

let a = 1;
let b = 2;
let c = 3;

在es6中:

let [a,b,c] = [1,2,3];

数组中的a=1,b=2,c=3

let [foo] = [];
let [bar, foo] = [1];

这里的foo=空值,也就是undefined
第二个数组中,只有bar被赋值,bar=1,foo并又没被赋值,foo=空值,也是undefined

02.对象解构(左边是声明的有{}来包裹,右边是对象名,或者也是用{}来包裹)
解构可以用于对象

let node = {
    type:'identifier',
    name:'foo'
}

let {type,name} = node;
console.log(type,name)//identifier foo

其中,第二段代码let {type,name} = node; 中的type和name是必须和对象的属性名一样才可以。如果对象的属性名改了,第二段代码中的字段也要相应的发生改变。
用剩余运算符:

let obj = {
    a:{
        name:'张三'
    },
    b:[],
    c:'hello world'
}
//可忽略 忽略b,c属性
let {a} = obj;
//剩余运算符 使用此法将其它属性展开到一个对象中存储
let {a,...res} = obj;
console.log(a,res);


比如说这个对象obj,有三个属性,一个是a,一个是数组b,一个是字符串c,
第二段代码let {a} = obj,只是将obj中的a赋值给了a,其他的并没有赋值
用剩余运算符…变量名,这样的话,就会把obj对象的除了a以外的参数,分割成一个个的对象赋值给一个数组,这个数组的名字叫做变量名,这里也就是res。

默认赋值:

let {a,b = 10} = {a:20};

b的默认赋值是10,如果没有对b进行赋值的话,b就会用默认值。

函数参数解构赋值:

function add([x, y]){
  return x + y;
}

add([1, 2]); // 3

这里的参数是一个数组,直接用一个数组来实例化参数

function addCart(n,num=0){
    
    return n+num;
}
addCart(10);//10
addCart(10,20); //30

这里用默认值,用一个参数,那个用默认值的参数会用默认值来赋值。也可以都赋值。

ES6 (js)_第4张图片
ES6 (js)_第5张图片
ES6 (js)_第6张图片
ES6 (js)_第7张图片
函数的扩展:

在之前的es5中,函数参数不能直接为函数的参数指定默认值,只能采用变通的方法

function log(x,y){
    y = y || 'world';
    console.log(x,y);
}
log('hello');//hello world
log('hello','china') //hello china
log('hello','')//hello world


js中的逻辑运算符:
js中的或运算||

let 变量 = 表达式1 || 表达式2

运算逻辑如下:

第 1 步:计算第一个操作数(左侧的表达式1)的值。

第 2 步:检测第一个操作数的值。如果左侧表达式的值可转换为 true,那么就会结束运算,直接返回第一个操作数的值。(没有赋值的表达式默认是false)

第 3 步:如果第一个操作数可以转换为 false,则计算第二个操作数(右侧的表达式2)的值。

第 4 步:返回第二个操作数的值。

总结是:或运算就是左边的是真的话,返回左边的表达式,如果左边的是假的话,返回右边的表达式


js中的与运算&&

let 变量 = 表达式1 && 表达式2

运算逻辑如下:

第 1 步:计算第一个操作数(左侧表达式)的值。

第 2 步:检测第一个操作数的值。如果左侧表达式的值可转换为 false(如 null、undefined、NaN、0、“”、false),那么就会结束运算,直接返回第一个操作数的值。

第 3 步:如果第一个操作数可以转换为 true,则计算第二个操作数(右侧表达式)的值。

第 4 步:返回第二个操作数的值。
总结是:左边的是真的话,返回右边的表达式,如果左边是假的话,返回左边的表达式
(也就是运算结果的真假,左边是真的,那结果取决于右边的表达式,直接返回右边的表达式即可;左边的表达式也就是假的话,结果一定是假,那么直接返回左边的表达式即可)

es6中:采用直接默认赋值的方法,即直接写在参数定义的后面。

function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello


默认的参数赋值可以是一个函数来赋值:

function getVal(val) {
    return val + 5;
}
function add2(a, b = getVal(5)) {
    return a + b;
}
console.log(add2(10));//20

rest参数:
ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

function add(...values) {
 
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10


上面代码的add函数是一个求和函数,利用 rest 参数,可以向该函数传入任意数目的参数。

箭头函数

ES6允许使用箭头=>定义函数

let f = v=>v;
//等同于
let f = function(v){
    return v;
}
// 有一个参数
let add = value => value;

//等同于
let add  = function(value ){
    return value ;
}

// 有两个参数
let add = (value,value2) => value + value2;

let add = (value1,value2)=>{
    
    return value1 + value2;
} 

//等同于
let add  = function(value1,value2 ){
    return value1 + value2;
}
// 无参数
let fn = () => "hello world";
//等同于
let add  = function(){
    return "hello world";
}
//如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
let getId = id => ({id: id,name: 'mjj'}) //注意
let obj = getId(1);

//等同于
let add  = function(id){
	 return {
	id:‘id’   ,
	name:‘mjj’
	}
}

ES6 (js)_第8张图片
使用注意点:
没有this绑定

let PageHandler = {
    id:123,
    init:function(){
        document.addEventListener('click',function(event) {
            this.doSomeThings(event.type);
        },false);
    },
    doSomeThings:function(type){
        console.log(`事件类型:${type},当前id:${this.id}`);
    }
}
PageHandler.init();

//解决this指向问题
let PageHandler = {
    id: 123,
    init: function () {
        // 使用bind来改变内部函数this的指向
        document.addEventListener('click', function (event) {
            this.doSomeThings(event.type);
        }.bind(this), false);
    },
    doSomeThings: function (type) {
        console.log(`事件类型:${type},当前id:${this.id}`);
    }
}
PageHandler.init();

let PageHandler = {
    id: 123,
    init: function () {
        // 箭头函数没有this的指向,箭头函数内部的this值只能通过查找作用域链来确定

        // 如果箭头函数被一个非箭头函数所包括,那么这里的this的值与该非箭头函数的所属对象相等,否则 则是全局的window对象
        document.addEventListener('click', (event) => {
            console.log(this);
            this.doSomeThings(event.type);
        }, false);
    },
    doSomeThings: function (type) {
        console.log(`事件类型:${type},当前id:${this.id}`);
    }
}
PageHandler.init();


注解:
bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值(每一个函数都有一个this属性,指向这个方法所属的对象)会被绑定到传入bind()中的第一个参数的值,表示是这个对象调用了这个函数,例如:f.bind(obj),实际上可以理解为obj.f(),这时f函数体内的this自然指向的是obj;
例如:执行以下的代码

 var a = {
    b: function() {
      var func = function() {
        console.log(this.c);
      }
      func();
    },
    c: 'hello'
  }
  a.b(); 
  console.log(a.c);

那么答案是什么呢?undefined和hello,大家可以打印看下,这个就是因为fun()这个函数执行的时候他的函数上下文为window,而a.b()的这个函数的执行的时候函数上下文this为a对象是什么意思呢?

 var a = {
    b: function() {
      console.log(this.c); //hello  
      var func = function() {
        console.log(this.c); //undefined
      }
      func();
    },
    c: 'hello'
  }
  a.b(); 

当我们希望func()他的输出的值就是为hrllo怎么办
方法一:改变this的值

 var a = {
    b: function() {
      var _this = this; // 通过赋值的方式将this赋值给that
      var func = function() {
        console.log(_this.c);
      }
      func();
    },
    c: 'hello'
  }
  a.b(); // hello
  console.log(a.c); // hello

方法二:绑定this的值发生改变

/ 使用bind方法一
  var a = {
    b: function() {
      var func = function() {
        console.log(this.c);
      }.bind(this);
      func();
    },
    c: 'hello'
  }
  a.b(); // hello
  console.log(a.c); // hello


这里我们以a.b()的形式去执行a对象中的b这个函数,是经过对象a的所以当我们来执行a对象中b函数的时候找this就会先找到a对象所以在a对象中的b这个函数中的this为a对象,所以这个时候bind,绑定的this也就是为a对象了。

ES6 (js)_第9张图片
ES6 (js)_第10张图片

这里的Person先是采用了无参数的函数,返回是一个空的对象。


对象的扩展
属性的简洁表示法

const name = '张三';
const age = 19;
const person = {
    name, //等同于name:name
    age,//等同于age:age,前一个是对象person的属性,后一个是之前声明的变量 const age
    // 方法也可以简写
    sayName() {
        console.log(this.name);
    }
}
person.sayName();


这种写法用于函数的返回值,将会非常方便。

function getPoint() {
  const x = 1;
  const y = 10;
  return {x, y};
}

getPoint()
// {x:1, y:10}

对象扩展运算符

const [a, ...b] = [1, 2, 3];
a // 1
b // [2, 3]

解构赋值
对象的解构赋值用于从一个对象取值,相当于将目标对象自身的所有可遍历的(enumerable)、但尚未被读取的属性,分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面。

let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }

注意:解构赋值必须是最后一个参数,否则会报错

扩展运算符
对象的扩展运算符(…)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。

let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }

Promise(我的想法是类似于ajax的异步通信)
Promise 是异步编程的一种解决方案:
从语法上讲,Promise是一个对象,通过它可以获取异步操作的消息;
从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
promise有三种状态:pending(等待态),fulfilled(成功态),rejected(失败态);
状态一旦改变,就不会再变。
创造promise实例后,它会立即执行。


Class的基本用法

简介
JavaScript语言中,生成实例对象的传统方法是通过构造函数

function Person(name,age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayName  = function() {
    return this.sayName;
}
let p = new Person('小马哥',18);
console.log(p);


上面这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大,很容易让新学习这门语言的程序员感到困惑
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的class改写,就是下面这样
javascript复制代码

class Person {
    // constructor方法 是类的默认方法,通过new命令生成对象实例时,自动调用该方法,一个类必须有constructor方法,如果没有定义,会被默认添加
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    //等同于Person.prototype = function sayName(){}
    sayName(){
        return this.name;
    }
}
console.log(Person===Person.prototype.constructor)


类的方法内部如果含有this,它默认指向类的实例

你可能感兴趣的:(es6)