ES6课程简易理解

ES6 介绍

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

为什么要学习 ES6

  1. ES6 的版本变动内容最多,具有里程碑意义
  2. ES6 加入许多新的语法特性,编程实现更简单、高效
  3. ES6 是前端发展趋势,就业必备技能

ES6新增部分

let 和 const

ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

{
  let a = 10;
  var b = 1
}
console.log(a) 
console.log(b) 

上面代码在代码块之中,分别用letvar声明了两个变量。然后在代码块之外调用这两个变量,结果let声明的变量报错,var声明的变量返回了正确的值。这表明,let声明的变量只在它所在的代码块有效。 而var 声明变量进行了变量提升

let 不存在变量提升

var命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。这种现象多多少少是有些奇怪的,按照一般的逻辑,变量应该在声明语句之后才可以使用。 let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。

// var 的情况
console.log(foo); 
var foo = 2;

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

let不允许重复声明

function func() {
  let a = 10;
  var a = 1;
}

function func() {
  let a = 10;
  let a = 1;
}

const命令

const声明一个只读的常量。一旦声明,常量的值就不能改变。 const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

const a = 3.1415;
console.log(a) // 3.1415

a = 3;
// TypeError: Assignment to constant variable.

const的作用域与let命令相同:只在声明所在的块级作用域内有效。

解构赋值

ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值

1. 数组的结构
      const F5 = ['小沈阳','刘能','赵四','宋小宝','安玲玲'];
      let [xiao, liu, zhao, song,an] = F5;
      console.log(xiao); 
      console.log(liu);
      console.log(zhao);
      console.log(song);
2. 对象的解构
       const zhao = {
             name: '赵本山',
             age: '不详',
             xiaopin: function(){
                  console.log("我可以演小品");
                  }
          };
     let {name, age, xiaopin} = zhao;
     console.log(name);
     console.log(age);
     console.log(xiaopin);
     xiaopin();

字符串的扩展

模板字符串

ES6 引入新的声明字符串的方式 『``』

  1. 声明
 let str = `我也是一个字符串哦!`;

 console.log(str, typeof str);
  1. 内容中可以直接出现换行
es6:  let str = `<ul>                       传统:let str = '<ul>'+ 
        <li>沈腾</li>                               '<li>沈腾</li>'+ 
         <li>玛丽</li>                              '<li>沈腾</li>'+
        <li>魏翔</li>                               '<li>魏翔</li>'+
        <li>艾伦</li>                               '<li>魏翔</li>'+
       </ul>`;                                         ' </ul>';
  1. 变量拼接
 let lovest = '魏翔';

 let out = `${lovest}是我心目中最搞笑的演员!!`;

  console.log(out);

函数扩展

rest 参数 ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments

     // ES5 获取实参的方式
         function date(){
           console.log(arguments);
          }
         date('白芷','阿娇','思慧');
     // rest 参数
         function date(...args){
                 console.log(args);
         }
         date('阿娇','柏芝','思慧');
   // rest 参数必须要放到参数最后
       function fn(a,b,...args){  
           console.log(a);
           console.log(b);
           console.log(args); 
       }
       fn(1,2,3,4,5,6);

箭头函数 ES6 允许使用“箭头”(=>)定义函数。

var f = v => v;

// 等同于
var f = function (v) {
  return v;
}
//声明一个函数
     let fn = function(){}
     let fn = (a,b) => {
       return a + b;
      }
 //调用函数
        let result = fn(1, 2);
        console.log(result);
//1. this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
        function getName(){
            console.log(this.name);
        }
        let getName2 = () => {
            console.log(this.name);
        }

        //设置 window 对象的 name 属性
        window.name = '尚硅谷';
        const school = {
            name: "ATGUIGU"
        }

        //直接调用
        getName();
        getName2();

       //call 方法调用
        getName.call(school);
        getName2.call(school);

//2. 不能作为构造实例化对象
        let Person = (name, age) => {
            this.name = name;
            this.age = age;
         }
         let me = new Person('xiao',30);
         console.log(me);
//3. 箭头函数的简写
           1) 省略小括号, 当形参有且只有一个的时候
            let add = n => {
                return n + n;
            }
             console.log(add(9));
            2) 省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略
               而且语句的执行结果就是函数的返回值
            let pow = n => n * n;
                
            console.log(pow(8));

箭头函数练习

  1. 点击 div 2s 后颜色变成『粉色』
  2. 从数组中返回偶数的元素

展开运算符 […]

第一个叫做 展开运算符(spread operator),作用是和字面意思一样,就是把东西展开。可以用在arrayobject上都行。
比如:

let a = [1,2,3];
console.log(...a)
let b = [0, ...a, 4]; // [0,1,2,3,4]

let obj = { a: 1, b: 2 };
let obj2 = { ...obj, c: 3 }; // { a:1, b:2, c:3 }
let obj3 = { ...obj, a: 3 }; // { a:3, b:2 }

Es6模块化

模块功能主要由两个命令构成:exportimportexport命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个 JS 文件,里面使用export命令输出变量。

// profile.js
//分别暴露
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

export的写法,除了像上面这样,还有另外一种。

// profile.js
//统一暴露
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export { firstName, lastName, year };

export最后一种写法

//默认暴露
export default {
  school: 'ATGUIGU',
  change: function(){
        console.log("我们可以改变你!!");
  }
}

使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。

// main.js
import { firstName, lastName, year } from './profile.js';

function setName(element) {
  element.textContent = firstName + ' ' + lastName;
}

上面代码的import命令,用于加载profile.js文件,并从中输入变量。import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。

如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。

import { lastName as surname } from './profile.js';

export default 命令

// export-default.js
export default function foo() {
  console.log('foo');
}

// 或者写成

function foo() {
  console.log('foo');
}

export default foo;

下面比较一下默认输出和正常输出。

// 第一组
export default function crc32() { // 输出
  // ...
}
import crc32 from 'crc32'; // 输入
// 第二组
export function crc32() { // 输出
  // ...
};
import {crc32} from 'crc32'; // 输入

上面代码的两组写法,第一组是使用export default时,对应的import语句不需要使用大括号;第二组是不使用export default时,对应的import语句需要使用大括号。

export default命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此export default命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能唯一对应export default命令。

ES6 promise

回调地狱

先了解一下回调地狱

第一种没有产生回调地狱之前
在这里插入图片描述

形成回调地狱
在这里插入图片描述

就是一个函数要去拿另一个函数内部去拿他的属性—<注意:闭包也有这个意思,但是闭包是在外部执行了,在另一个函数内部做返回处理>,且该函数在另一个函数内部做执行,一次外部函数一个接一个放到另一个函数内部去拿值,第一层失败下面全部失败。

实例化Promise

1.什么是Promise
Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。(ps:什么是原型:https://blog.csdn.net/qq_34645412/article/details/105997336)

Promise对象有以下两个特点。

(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、resolved(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为resolved和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。下面先new一个对象

 //实例化 Promise 对象
        const p = new Promise(function(resolve, reject){
            setTimeout(function(){
                
                let data = '数据库中的用户数据';
                resolve(data);

               //let err = '数据读取失败';
                //reject(err);
            }, 1000);
        });

        //调用 promise 对象的 then 方法
        p.then(function(value){
            console.log(value);
        }, function(reason){
            console.error(reason);
        })

刷新页面会发现控制台直接console出来

其执行过程是:执行了一个异步操作,也就是setTimeout,2秒后,输出“执行完成”,并且调用resolve方法。

注意!我只是new了一个对象,并没有调用它,我们传进去的函数就已经执行了,这是需要注意的一个细节。所以我们用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数,如:

 <div onclick='promiseClick()'>开始异步请求</div>

const promiseClick =()=>{
	 console.log('点击方法被调用')
	 let p = new Promise(function(resolve, reject){
		//做一些异步操作
		setTimeout(function(){
				console.log('执行完成Promise');
				resolve('要返回的数据可以任何数据例如接口返回数据');
			}, 2000);
		});
        return p
	}

resolve是个什么鬼

我们包装好的函数最后,会return出Promise对象,也就是说,执行这个函数我们得到了一个Promise对象。接下来就可以用Promise对象上有then、catch方法了,这就是Promise的强大之处了,看下面的代码:

 promiseClick().then(function (data) {
      console.log(data);
      //后面可以用传过来的数据做些其他操作
      //......
    })

先是方法被调用起执行了promise,最后执行了promise的then方法,then方法是一个函数接受一个参数是接受resolve返回的数据这事就输出了‘要返回的数据可以任何数据例如接口返回数据’

这时候你应该有所领悟了,原来then里面的函数就跟我们平时的回调函数一个意思,能够在promiseClick这个异步任务执行完成之后被执行。这就是Promise的作用了,简单来讲,就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。

你可能会觉得在这个和写一个回调函数没有什么区别;那么,如果有多层回调该怎么办?如果callback也是一个异步操作,而且执行完后也需要有相应的回调函数,该怎么办呢?总不能再定义一个callback2,然后给callback传进去吧。而Promise的优势在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。

所以:精髓在于:Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。

reject的用法
以上是对promise的resolve用法进行了解释,相当于resolve是对promise成功时候的回调,它把promise的状态修改为fullfiled,那么,reject就是失败的时候的回调,他把promise的状态修改为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。

function promiseClick(){
		let p = new Promise(function(resolve, reject){
			setTimeout(function(){
				var num = Math.ceil(Math.random()*20); //生成1-10的随机数
				console.log('随机数生成的值:',num)
				if(num<=10){
					resolve(num);
				}
				else{
					reject('数字太于10了即将执行失败回调');
				}
			}, 2000);
		   })
		   return p
	   }
 
	promiseClick().then(
		function(data){
			console.log('resolved成功回调');
			console.log('成功回调接受的值:',data);
		}, 
		function(reason){
			console.log('rejected失败回调');
			console.log('失败执行回调抛出失败原因:',reason);
		}
	);	

catch的用法

与Promise对象方法then方法并行的一个方法就是catch,与try catch类似,catch就是用来捕获异常的,也就是和then方法中接受的第二参数rejected的回调是一样的,如下:

function promiseClick(){
		let p = new Promise(function(resolve, reject){
			setTimeout(function(){
				var num = Math.ceil(Math.random()*20); //生成1-10的随机数
				console.log('随机数生成的值:',num)
				if(num<=10){
					resolve(num);
				}
				else{
					reject('数字太于10了即将执行失败回调');
				}
			}, 2000);
		   })
		   return p
	   }
 
	promiseClick().then(
		function(data){
			console.log('resolved成功回调');
			console.log('成功回调接受的值:',data);
		}
	)
	.catch(function(reason){
		console.log('catch到rejected失败回调');
		console.log('catch失败执行回调抛出失败原因:',reason);
	});	

封装ajax

// Promise 封装 ajax
function fetch(method, url, data){
    return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest();
        xhr.open(method, url, true);
        if(data!=null){
            // 视情况添加请求头
            xhr.send(data);
        }else{
              xhr.send();
        }
       
        xhr.onreadystatechange = function() {
            if(xhr.status === 200 && xhr.readyState === 4){
                resolve(xhr.responseText);
            } else {
                reject(xhr.responseText);
            }
        }
        })
}

// 使用
fetch("GET", "/some/url.json", null)
.then(result => {
    console.log(result);
}).catch(error=>{
    console.log(error);
})

  // 视情况添加请求头
        xhr.send(data);
    }else{
          xhr.send();
    }
   
    xhr.onreadystatechange = function() {
        if(xhr.status === 200 && xhr.readyState === 4){
            resolve(xhr.responseText);
        } else {
            reject(xhr.responseText);
        }
    }
    })

}

// 使用
fetch(“GET”, “/some/url.json”, null)
.then(result => {
console.log(result);
}).catch(error=>{
console.log(error);
})


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~Wforikl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值