精华内容
下载资源
问答
  • 2019-01-05 18:17:46

    import()函数

    简介

    前面介绍过,import命令会被 JavaScript 引擎静态分析,先于模块内的其他模块执行(叫做”连接“更合适)。所以,下面的代码会报错。

    
    
    1. // 报错
    2. if (x === 2) {
    3. import MyModual from './myModual';
    4. }

    上面代码中,引擎处理import语句是在编译时,这时不会去分析或执行if语句,所以import语句放在if代码块之中毫无意义,因此会报句法错误,而不是执行时错误。也就是说,importexport命令只能在模块的顶层,不能在代码块之中(比如,在if代码块之中,或在函数之中)。

    这样的设计,固然有利于编译器提高效率,但也导致无法在运行时加载模块。在语法上,条件加载就不可能实现。如果import命令要取代 Node 的require方法,这就形成了一个障碍。因为require是运行时加载模块,import命令无法取代require的动态加载功能。

    
    
    1. const path = './' + fileName;
    2. const myModual = require(path);

    上面的语句就是动态加载,require到底加载哪一个模块,只有运行时才知道。import语句做不到这一点。

    因此,有一个提案,建议引入import()函数,完成动态加载。

    
    
    1. import(specifier)

    上面代码中,import函数的参数specifier,指定所要加载的模块的位置。import命令能够接受什么参数,import()函数就能接受什么参数,两者区别主要是后者为动态加载。

    ES6 import()返回一个 Promise 对象。下面是一个例子。

    
    
    1. const main = document.querySelector('main');
    2. import(`./section-modules/${someVariable}.js`)
    3. .then(module => {
    4. module.loadPageInto(main);
    5. })
    6. .catch(err => {
    7. main.textContent = err.message;
    8. });

    import()函数可以用在任何地方,不仅仅是模块,非模块的脚本也可以使用。它是运行时执行,也就是说,什么时候运行到这一句,也会加载指定的模块。另外,import()函数与所加载的模块没有静态连接关系,这点也是与import语句不相同。

    import()类似于 Node 的require方法,区别主要是前者是异步加载,后者是同步加载。

    适用场合

    下面是import()的一些适用场合。

    (1)按需加载。

    import()可以在需要的时候,再加载某个模块。

    
    
    1. button.addEventListener('click', event => {
    2. import('./dialogBox.js')
    3. .then(dialogBox => {
    4. dialogBox.open();
    5. })
    6. .catch(error => {
    7. /* Error handling */
    8. })
    9. });

    上面代码中,import()方法放在click事件的监听函数之中,只有用户点击了按钮,才会加载这个模块。

    (2)条件加载

    import()可以放在if代码块,根据不同的情况,加载不同的模块。

    
    
    1. if (condition) {
    2. import('moduleA').then(...);
    3. } else {
    4. import('moduleB').then(...);
    5. }

    上面代码中,如果满足条件,就加载模块 A,否则加载模块 B。

    (3)动态的模块路径

    import()允许模块路径动态生成。

    
    
    1. import(f())
    2. .then(...);

    上面代码中,根据函数f的返回结果,加载不同的模块。

    注意点

    import()加载模块成功以后,这个模块会作为一个对象,当作then方法的参数。因此,可以使用对象解构赋值的语法,获取输出接口。

    
    
    1. import('./myModule.js')
    2. .then(({export1, export2}) => {
    3. // ...·
    4. });

    上面代码中,export1export2都是myModule.js的输出接口,可以解构获得。

    如果模块有default输出接口,可以用参数直接获得。

    
    
    1. import('./myModule.js')
    2. .then(myModule => {
    3. console.log(myModule.default);
    4. });

    上面的代码也可以使用具名输入的形式。

    
    
    1. import('./myModule.js')
    2. .then(({default: theDefault}) => {
    3. console.log(theDefault);
    4. });

    如果想同时加载多个模块,可以采用下面的写法。

    
    
    1. Promise.all([
    2. import('./module1.js'),
    3. import('./module2.js'),
    4. import('./module3.js'),
    5. ])
    6. .then(([module1, module2, module3]) => {
    7. ···
    8. });

    import()也可以用在 async 函数之中。

    
    
    1. async function main() {
    2. const myModule = await import('./myModule.js');
    3. const {export1, export2} = await import('./myModule.js');
    4. const [module1, module2, module3] =
    5. await Promise.all([
    6. import('./module1.js'),
    7. import('./module2.js'),
    8. import('./module3.js'),
    9. ]);
    10. }
    11. main();
    更多相关内容
  • es6中通常用let和const来声明,let表示变量、const表示常量。 特点: let 和 const 都是块级作用域。以{}代码块作为作用域范围 只能在代码块里面使用。 不存在变量提升,只能先声明再使用,否则会报错。在代码...

    目录

    1、新增声明命令let和const

    2、模板字符串(Template String)

    3、函数的扩展

    (1)、函数的默认参数

    (2)、箭头函数 

    4、对象的扩展 

    (1)、属性的简写。

    (2)、方法的简写。省略冒号与function关键字。

    (3)、Object.keys()方法,获取对象的所有属性名或方法名(不包括原形的内容),返回一个数组。

    (4)、Object.assign (),assign方法将多个原对象的属性和方法都合并到了目标对象上面。可以接收多个参数,第一个参数是目标对象,后面的都是源对象。

    5、for...of  循环

    6、import和export

    7、Promise对象

    8、解构赋值

    (1)、数组的解构赋值

    (2)、对象的解构赋值

    9、set数据结构

    10、Spread Operator 展开运算符(...)

    (1)、将字符串转成数组

    (2)、将集合转成数组

    (3)、两个数组的合并

    (4)、在函数中,用来代替arguments参数


    1、新增声明命令letconst

    es6中通常用 let 和 const 来声明,let 表示变量const 表示常量

    特点:

    • let 和 const 都是块级作用域。以{}代码块作为作用域范围 只能在代码块里面使用。
    • 不存在变量提升,只能先声明再使用,否则会报错。在代码块内,在声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
    • 在同一个代码块内,不允许重复声明。
    • const声明的是一个只读常量,在声明时就需要赋值。(如果 const 的是一个对象,对象所包含的值是可以被修改的。抽象一点儿说,就是对象所指向的地址不能改变,而变量成员是可以修改的。)

    2、模板字符串(Template String)

    用一对反引号(`)标识,它可以当作普通字符串使用,也可以用来定义多行字符串,也可以在字符串中嵌入变量,js表达式或函数,变量、js表达式或函数需要写在${ }中。

    var str = `abc
    def
    gh`;
    console.log(str);
    let name = "小明";
    function a() {
        return "ming";
    }
    console.log(`我的名字叫做${name},年龄${17+2}岁,性别${'男'},游戏ID:${a()}`);

    3、函数的扩展

    (1)、函数的默认参数

    ES6为参数提供了默认值。在定义函数时便初始化了这个参数,以便在参数没有被传递进去时使用。

    function A(a,b=1){
        console.log(a+b);
    }
    A(1);    //2
    A(2+3);  //5

    (2)、箭头函数 

    在es6中,提供了一种简洁的函数写法,我们称作“箭头函数”。

    写法:函数名=(形参)=>{……}     当函数体中只有一个表达式时,{}和return可以省略,当函数体中形参只有一个时,()可以省略。

    特点:箭头函数中的this始终指向箭头函数定义时的离this最近的一个函数,如果没有最近的函数就指向window。

    //省略写法
    var people = name => 'hello' + name;
     
    var getFullName = (firstName, lastName) => {
        var fullName = firstName + lastName;
        return fullName;
    } 

    4、对象的扩展 

    (1)、属性的简写。

    ES6 允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值。

    var foo = 'bar';
    var baz = {foo};  //等同于  var baz = {foo: foo};

    (2)、方法的简写。省略冒号与function关键字。

    var o = {
      method() {
        return "Hello!";
      }
    };
     
    // 等同于
    var o = {
      method: function() {
        return "Hello!";
      }
    };

    (3)、Object.keys()方法,获取对象的所有属性名或方法名(不包括原形的内容),返回一个数组。

    var obj={name: "john", age: "21", getName: function () { alert(this.name)}};
    console.log(Object.keys(obj));    // ["name", "age", "getName"]
    console.log(Object.keys(obj).length);    //3
     
    console.log(Object.keys(["aa", "bb", "cc"]));    //["0", "1", "2"]
    console.log(Object.keys("abcdef"));    //["0", "1", "2", "3", "4", "5"]

    (4)、Object.assign (),assign方法将多个原对象的属性和方法都合并到了目标对象上面。可以接收多个参数,第一个参数是目标对象,后面的都是源对象。

    var target  = {}; //目标对象
    var source1 = {name : 'ming', age: '19'}; //源对象1
    var source2 = {sex : '女'}; //源对象2
    var source3 = {sex : '男'}; //源对象3,和source2中的对象有同名属性sex
    Object.assign(target,source1,source2,source3);
     
    console.log(target);    //{name : 'ming', age: '19', sex: '男'}

    5、for...of  循环

    是遍历所有数据结构的统一的方法。for...of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、Generator 对象,以及字符串。

    var arr=["小林","小吴","小佳"];
    for(var v of arr){
        console.log(v);	
    }
    //小林 
    //小吴 
    //小佳

    6、import和export

    ES6标准中,JavaScript原生支持模块(module)了。这种将JS代码分割成不同功能的小块进行模块化,将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用。

    export用于对外输出本模块(一个文件可以理解为一个模块)变量的接口。

    import用于在一个模块中加载另一个含有export接口的模块。

    import和export命令只能在模块的顶部,不能在代码块之中。

    //导入部分
    //全部导入
    import Person from './example'
     
    //将整个模块所有导出内容当做单一对象,用as起别名
    import * as example from "./example.js"
    console.log(example.name)
    console.log(example.getName())
     
    //导入部分
    import { name } from './example'
     
    //导出部分
    // 导出默认
    export default App
     
    // 部分导出
    export class User extend Component {};

    7、Promise对象

    Promise是异步编程的一种解决方案,将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

    它有三种状态,分别是pending-进行中、resolved-已完成、rejected-已失败。

    Promise 构造函数包含一个参数和一个带有 resolve(解析)和 reject(拒绝)两个参数的回调。在回调中执行一些操作(例如异步),如果一切都正常,则调用 resolve,否则调用 reject。对于已经实例化过的 promise 对象可以调用 promise.then() 方法,传递 resolve 和 reject 方法作为回调。then()方法接收两个参数:onResolve和onReject,分别代表当前 promise 对象在成功或失败时。
     

    var promise = new Promise((resolve, reject) => {
        var success = true;
        if (success) {
            resolve('成功');
        } else {
            reject('失败');
        }
    }).then(
        (data) => { console.log(data)},
        (data) => { console.log(data)}
    )

    promise的执行过程

    setTimeout(function() {
        console.log(0);
    }, 0);
    var promise = new Promise((resolve, reject) => {
        console.log(1);
        setTimeout(function () {
            var success = true;
            if (success) {
                resolve('成功');
            } else {
                reject('失败');
            }
        },2000);
    }).then(
        (data) => { console.log(data)},
        (data) => { console.log(data)}
    );
    console.log(promise);	//<pending> 进行中
    setTimeout(function () {
        console.log(promise);	//<resolved> 已完成
    },2500);
    console.log(2);
     
    //1
    //Promise {<pending>}
    //2
    //0
    //成功
    //Promise {<resolved>: undefined}

    8、解构赋值

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

    (1)、数组的解构赋值

    数组中的值会自动被解析到对应接收该值的变量中,数组的解构赋值要一一对应 如果有对应不上的就是undefined

    var [name, pwd, sex]=["小周", "123456", "男"];
    console.log(name) //小周
    console.log(pwd)//123456
    console.log(sex)//男

    (2)、对象的解构赋值

    对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

    var obj={name:"小周", pwd:"123456", sex:"男"}
    var {name, pwd, sex}=obj;
    console.log(name) //小周
    console.log(pwd)//123456
    console.log(sex)//男
     
    //如果想要变量名和属性名不同,要写成这样
    let { foo: foz, bar: baz } = { foo: "aaa", bar: "bbb" };
    console.log(foz) // "aaa"
    console.log(foo) // error: foo is not defined

    9、set数据结构

    Set数据结构,类似数组。所有的数据都是唯一的,没有重复的值。它本身是一个构造函数。

    属性和方法:

    size 数据的长度
    add() 添加某个值,返回 Set 结构本身。
    delete() 删除某个值,返回一个布尔值,表示删除是否成功。
    has() 查找某条数据,返回一个布尔值。
    clear() 清除所有成员,没有返回值。
    应用:数组去重。

    var arr = [1,1,2,2,3];
    var s = new Set(arr);
    console.log(s);	//{1, 2, 3}
     
    console.log(s.size);	//3
    console.log(s.add(4));	//{1, 2, 3, 4}
    console.log(s.delete(4));	//true
    console.log(s.has(4));	//false
    s.clear();

    10、Spread Operator 展开运算符(...)

    (1)、将字符串转成数组

    var str="abcd";
    console.log([...str]) // ["a", "b", "c", "d"]

    (2)、将集合转成数组

    var sets=new Set([1,2,3,4,5])
    console.log([...sets]) // [1, 2, 3, 4, 5]

    (3)、两个数组的合并

    var a1=[1,2,3];
    var a2=[4,5,6];
    console.log([...a1,...a2]); //[1, 2, 3, 4, 5, 6]

    (4)、在函数中,用来代替arguments参数

    rest参数  …变量名称

    rest 参数是一个数组 ,它的后面不能再有参数,不然会报错

    function func(...args){
        console.log(args);//[1, 2, 3, 4]
    }
    func(1, 2, 3, 4);
     
    function f(x, ...y) {
        console.log(x);
        console.log(y);
    }
    f('a', 'b', 'c');     //a 和 ["b","c"]
    f('a')                //a 和 []
    f()                   //undefined 和 []

    展开全文
  • Es6 和 同步异步任务

    多人点赞 2021-10-17 20:43:49
    导入其它模块成员使用 import 关键字 向外共享模块成员使用 export 关键字 1.2 在 node.js 中体验 ES6 模块化 node.js 中默认仅支持 CommonJS 模块化规范,若想基于 node.js 体验与学习 ES6 的模块化语法,...

    1. Es6 模块化

    1.1 ES6 模块化规范中定义:

    • 每个 js 文件都是一个独立的模块

    • 导入其它模块成员使用 import 关键字

    • 向外共享模块成员使用 export 关键字

    1.2 在 node.js 中体验 ES6 模块化

    node.js 中默认仅支持 CommonJS 模块化规范,若想基于 node.js 体验与学习 ES6 的模块化语法,可以进行如下配置:

    • 确保安装了 v14.15.1 或更高版本的 node.js

      • node -v 命令可查看

    • 在 package.json 的根节点中添加 "type": "module" 节点

    1.3 ES6 模块化的基本语法

    • 默认导出与默认导入

      // export default 默认导出的成员
      let n1 = 10;
      let n2 = () => console.log('hello')
      export default {
       n1,
       n2
      }
      //每个模块中,只允许使用唯一的一次 export default,否则会报错!
      // import 接收名称 from '模块标识符'
    • 按需导出与按需导入

      • // export 按需导出的成员
        export let s1 = 'sss';
        export let s2 = () => console.log('hello');
      •  //import { s1 } from '模块标识符'
        // 每个模块中可以使用多次按需导出
        // 按需导入的成员名称必须和按需导出的名称保持一致
        // 按需导入时,可以使用 as 关键字进行重命名
        //  按需导入可以和默认导入一起使用
    • 直接导入并执行模块中的代码

      // import '模块标识符'
      // 如果只想单纯地执行某个模块中的代码,并不需要得到模块中向外共享的成员,可以执行该代码

    2. Promise

    2.1 回调地狱

    多层回调函数的相互嵌套,就形成了回调地狱. 其缺点

    • 代码耦合性太强,牵一发而动全身,难以维护

    • 大量冗余的代码相互嵌套,代码的可读性变差

    为了解决回调地狱的问题,ES6 中新增了 Promise 的概念。

    2.2 Promise 的基本概念

    • Promise 是一个构造函数

      • 创建 Promise 的实例 const p = new Promise()

      • new 出来的 Promise 实例对象,代表一个异步操作

    • Promise.prototype 上包含一个 .then() 方法

      • 每一次 new Promise() 构造函数得到的实例对象,都可以通过原型链的方式访问到 .then() 方法,例如 p.then()

    • .then() 方法用来预先指定成功和失败的回调函数

      // p.then(成功的回调函数,失败的回调函数)
      // p.then(result => { }, error => { })
      // 调用 .then() 方法时,成功的回调函数是必选的、失败的回调函数是可选的

    2.3 .then() 方法的特性

    如果上一个 .then() 方法中返回了一个新的 Promise 实例对象,则可以通过下一个 .then() 继续进行处理。通过 .then() 方法的链式调用,就解决了回调地狱的问题。

    2.4 通过 .catch 捕获错误

    在 Promise 的链式操作中如果发生了错误,可以使用 Promise.prototype.catch 方法进行捕获和处理

    2.5 Promise.all() 方法

    Promise.all() 方法会发起并行的 Promise 异步操作,等所有的异步操作全部结束后才会执行下一步的 .then操作(等待机制)

    2.6 Promise.race() 方法

    Promise.race() 方法会发起并行的 Promise 异步操作,只要任何一个异步操作完成,就立即执行下一步的 .then 操作(赛跑机制) .

    3. async 和 await

    3.1 什么是 async/await

    async/await 是 ES8(ECMAScript 2017)引入的新语法,用来简化 Promise 异步操作。

    3.2 async/await 的使用注意事项

    • 如果在 function 中使用了 await,则 function 必须被 async 修饰

    • 在 async 方法中,第一个 await 之前的代码会同步执行,await 之后的代码会异步执行

    async function fn(){
        const r1 = await Promise 对象
    }
    // 具名函数
    async const fn1 = async () => {
        const r1 = await Promise 对象
    }// 匿名函数

    4. EventLoop

    4.1 JavaScript 是单线程的语言

    JavaScript 是一门单线程执行的编程语言。也就是说,同一时间只能做一件事情。如果前一个任务非常耗时,则后续的任务就不得不一直等待,从而导致程序假死的问题。

    4.2 同步任务和异步任务

    为了防止某个耗时任务导致程序假死的问题,JavaScript 把待执行的任务分为了两类:

    • 同步任务(synchronous)

      • 又叫做非耗时任务,指的是在主线程上排队执行的那些任务 只有前一个任务执行完毕,才能执行后一个任务

    • 异步任务(asynchronous)

      • 又叫做耗时任务,异步任务由 JavaScript 委托给宿主环境进行执行

      • 当异步任务执行完成后,会通知 JavaScript 主线程执行异步任务的回调函数

    4.3 同步任务和异步任务的执行过程

    • 同步任务由 JavaScript 主线程次序执行

    • 异步任务委托给宿主环境执行

    • 已完成的异步任务对应的回调函数,会被加入到任务队列中等待执行

    • JavaScript 主线程的执行栈被清空后,会读取任务队列中的回调函数,依次序执行

    • JavaScript 主线程不断重复上面的第 4 步

    JavaScript 主线程从“任务队列”中读取异步任务的回调函数,放到执行栈中依次执行。这个过程是循环不断的,所以整个的这种运行机制又称为 EventLoop(事件循环)

    5. 宏任务和微任务

    JavaScript 把异步任务又做了进一步的划分,异步任务又分为两类,分别是:

    • 宏任务(macrotask)

      • 异步 Ajax 请求、

      • setTimeout、setInterval、

      • 文件操作

      • 其它宏任务

    • 微任务(microtask)

      • Promise.then、.catch 和 .finally

      • process.nextTick

      • 其它微任务

    5.1 宏任务和微任务的执行顺序

    每一个宏任务执行完之后,都会检查是否存在待执行的微任务,如果有,则执行完所有微任务之后,再继续执行下一个宏任务。

    展开全文
  • ES6新特性有哪些?

    千次阅读 2022-03-11 12:22:47
    ES6新特性有哪些? 一、新的原始类型和变量声明 1,symbol 在ES6之前,我们知道JavaScript支持8种数据类型:Object,String,Boolean,Number,Null,Undefined、Array、Function。现在,ES6新增了一种原始数据类型...

    ES6新特性有哪些?

    一、新的原始类型和变量声明

    1,symbol

    在ES6之前,我们知道JavaScript支持8种数据类型:Object,String,Boolean,Number,Null,Undefined、Array、Function。现在,ES6新增了一种原始数据类型:symbol,表示独一无二的值,即每个symbol类型的值都不相同。这让我想起了另一个特殊的值:NaN,想一想,他们是不是有一点类似呢!

    var sy = Symbol('test');
    var sy1 = Symbol('test');
    console.log(tepeof sy);   //'symbol'
    sy == sy1;   //false
    var sy2 = new Symbol('test');   //error : Symbol is not a constructor
    

    创建symbol数据类型的值时,需要给Symbol函数传递一个字符串,并且有一点特殊的是:不能使用new关键字调用它。另外,每个symbol类型值都是独一无二的,即使传递的是相同的字符串。

    2,let和const

    ES6新增了两个声明变量的关键字:let和const。

    他们声明的变量仅在let和const关键字所在的代码块内起作用,即在使用let和const的那一对大括号{}内起作用,也称块级作用域(ES6之前只有函数作用域和全局作用域)。

    let和const声明变量不会在预编译过程中有提升行为(在全局声明也不会变成window的属性),且同一变量不能重复声明。所以要使用这类变量,只能在let和const关键字之后使用它们。

    let和const关键字还有一个特性:“暂时性死区”,即在使用了该关键字的块级作用域中,其内部使用let和const关键字声明的变量与外部作用域中的变量相互隔绝,互不影响。即使是同名变量。

    var a = 1;
    {
       console.log(a);   //error Cannot access 'a' before initialization
       let a = 0;
       console.log(a);   //0
    }
    console.log(a);   //1
    

    const用来声明一个常量,声明时必须赋值,且一旦声明就不能改变。

    其实说const变量不能更改是不准确的,请看下面的例子:

    const obj = {
        name:'ren',
        age:12
    };
    obj = {};   //error
    obj.sex = male;
    consol.log(obj);   //{name:'ren',age:12;sex:'male'}
    

    const声明的如果是一个原始值,那么上面的说法是准确的,如果const声明的是一个引用值,那么更准确的说法应该是一个不能被重新赋值的变量。

    3,解构赋值

    解构赋值是对赋值运算符的扩展。它是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。

    let [a,b,c] = [1,2,3];
    console.log(a,b,c);    //1,2,3
    
    let [a,b,c] = [1,,3];
    console.log(a,b,c);    //1,undefined,3
    
    let [a,,b] = [1,2,3];
    console.log(a,b);//1,3
    
    let [a,..b] = [1,2,3];    //...是剩余运算符,表示赋值运算符右边除第一个值外剩余的都赋值给b
    console.log(a,b);//1,[2,3]
    

    事实上所有可枚举(iterable)的对象都可以使用解构赋值,例如数组,字符串对象,以及ES6新增的Map和Set类型。

    let arr = 'hello';
    let [a,b,c,d,e] = arr;
    console.log(a,b,c,d,e);  //'h','e','l','l','o'
    

    对象的解构赋值和数组类似,不过左边的变量名需要使用对象的属性名,并且用大括号{}而非中括号[]:

    let obj = {name:'ren',age:12,sex:'male'};
    let {name,age,sex} = obj;
    console.log(name,age,sex);  //'ren' 12 'male'
    let {name:myName,age:myAge,sex:mySex} = obj;  //自定义变量名
    console.log(myName,myAge,mySex);  //'ren' 12 'male'
    

    二  新的对象和方法

    1,Map和Set

    Map对象用于保存键值对,任何值JavaScript支持的值都可以作为一个键或者一个值。这听起来和对象差不多啊?其实它们还是有区别的:

    a) object的键只能是字符串或ES6的symbol值,而Map可以是任何值。

    b) Map对象有一个size属性,存储了键值对的个数,而object对象没有类似属性。

    let myMap = new Map([['name','ren'],['age',12]]);
    console.log(myMap);  //{'name'=>'ren','age'=>12}
    myMap.set('sex','male');
    console.log(myMap);  //{'name'=>'ren','age'=>12,'sex'=>'male'}
    myMap.get('name');  //'ren'
    myMap.has('age');  //true
    myMap.delete('age');  //true
    myMap.has('age');  //false
    myMap.get('age');  //undefined
    

    Map构造函数接收一个二维数组来创建一个Map对象。数组元素的第0位表示Map对象的key,第1位表示Map对象的value。

    Map对象使用set方法来新增数据,set方法接收两个参数,第一个表示key,第二个表示value。使用get方法获取数据,参数是对象的key。

    Map对象使用delete方法来删除数据,接收一个参数,表示需要被删除的key。

    Map对象使用has方法检测是否已经具有某个属性,返回boolean值。

    Set对象和Map对象类似,但它是用来存储一组唯一值的,而不是键值对。类似数组,但它的每个元素都是唯一的。

    let mySet = new Set([1,2,3]);
    console.log(mySet);  //{1,2,3}
    mySet.add(4);
    console.log(mySet);  //{1,2,3,4}
    mySet.delete(1);  //true
    mySet.has(1);  //false
    

    利用Set对象唯一性的特点,可以轻松实现数组的去重:

    let arr = [1,1,2,3,4,4];
    let mySet = new Set(arr);
    let newArr = Array.from(mySet);
    console.log(newArr);  //[1,2,3,4]
    

    2,对象新特性

    创建对象的字面量方式可以更加简洁。直接使用变量名作为属性,函数体作为方法,最终变量值变成属性值,函数名变成方法名。

     let name = 'ren';
     let age = 12;
     let myself = {
         name,
         age,
         say(){
             console.log(this.name);
         }
     };
    console.log(myself);  //{name:'ren',age:12,say:fn}
    myself.say();  //'ren'
    

    对象的拓展运算符(…)三点。用于拷贝目标对象所有可遍历的属性到当前对象。

    let obj = {name:'ren',age:12};
    let person = {...obj};
    console.log(person);//{name:'ren',age:12}
    obj == person;//false
    let another = {sex:'male'};
    let someone = {...person,...another};//合并对象
    console.log(someone);//{name:'ren',age:12,sex:'male'}
    

    ES6对象新增了两个方法,assign和is。

    assign用于浅拷贝源对象可枚举属性到目标对象。

    let source = {a:{ b: 1},b: 2};
    let target = {c: 3};
    Object.assign(target, source);
    console.log(target);  //{c: 3, a: {b:1}, b: 2}
    source.a.b = 2;
    console.log(target.a.b);  //2
    

    如果有同名属性,那么目标对象的属性值会被源对象的属性值覆盖。所以数组的表现就有一点特别了:

    Object.assign([1,2,3],[11,22,33,44]);//[11,22,33,44]
    

    数组的index就是属性名,当使用assign方法时,从第0位开始,目标数组的值便开始被源数组的值覆盖了。

    is方法和(===)功能基本类似,用于判断两个值是否绝对相等。

    Object.is(1,1);//true
    Object.is(1,true);//false
    Object.is([],[]);//false
    Object.is(+0,-0);//false
    Object.is(NaN,NaN);//true
    

    他们仅有的两点区别是,is方法可以区分+0还是-0,还有就是它认为NaN是相等的。

    3,字符串新方法

    includes()判断字符串是否包含参数字符串,返回boolean值。如果想要知道参数字符串出现的位置,还是需要indexOf或lastIndexOf方法。

    startsWith()/endsWith(),判断字符串是否以参数字符串开头或结尾。返回boolean值。这两个方法可以有第二个参数,一个数字,表示开始查找的位置。

    let str = 'blue,red,orange,white';
    str.includes('blue');//true
    str.startsWith('blue');//true
    str.endsWith('blue');//false
    

    repeat()方法按指定次数返回一个新的字符串。如果次数是大于0的小数则向下取整,0到-1之间的小数则向上取整,其他负数将抛出错误。

    console.log('hello'.repeat(2));//'hellohello'
    console.log('hello'.repeat(1.9));//'hello'
    console.log('hello'.repeat(-0.9));//''
    console.log('hello'.repeat(-1.9));//error
    

    padStart()/padEnd(),用参数字符串按给定长度从前面或后面补全字符串,返回新字符串。

    let arr = 'hell';
    console.log(arr.padEnd(5,'o'));  //'hello'
    console.log(arr.padEnd(6,'o'));  //'helloo'
    console.log(arr.padEnd(6));  //'hell  ',如果没有指定将用空格代替
    console.log(arr.padStart(5,'o'));  //'ohell'
    

    另外,如果字符串加上补全的字符串超出了给定的长度,那么,超出的部分将被截去。

    4,数组的新方法

    of()是ES6新增的用于创建数组的方法。of把传入的参数当做数组元素,形成新的数组。

    let arr = Array.of(1,'2',[3],{});
    console.log(arr);   //[1,'2',[3],{}]
    

    from()方法可以将可迭代对象转换为新的数组。函数可接受3个参数:第一个表示将被转换的可迭代对象,第二个是回调函数,将对每个数组元素应用该回调函数,然后返回新的值到新数组,第三个是回到函数内this的指向。后两个参数是可选的。

    let obj = {
        double(n) {
            return n * 2;
        }
    }
    let arr = [1, 2, 3];
    console.log(Array.from(arr, function (n){
        return this.double(n);
    }, obj)); // [2, 4, 6]
    

    find()和findIndex(),查找数组中符合条件的元素值或索引,方法不会修改原数组。

    接受一个回调函数作为参数,函数可以接受四个参数,分别是当前遍历到的元素,当前遍历到的索引,数组本身以及函数内this的指向。方法会把回调函数作用于每一个遍历到的元素,如果遍历到某一个元素可以使回调函数返回true,那么find方法会立即返回该元素,findIndex方法会返回该元素的索引。并终止继续遍历。

    如果有多个符合条件的,也将只返回第一个。如果遍历完整个数组也无法是回调函数返回true,那么find方法将返回undefined,findIndex方法将返回-1。

    let arr = [1,2,3,4,5];
    console.log(arr.find((ele) => {
        return ele === 1;
    }));//1
    console.log(arr.findIndex((ele) => {
        return ele > 4;
    }));  //4
    

    fill()/copyWithin(),替换数组中部分元素,会修改原数组。

    let arr = [1,2,3,4,5];
    console.log(arr.fill(0,0,3));//[0,0,0,4,5]
    //参数1表示目标值,参数2,3表示替换的始末位置,左闭右开区间。
    console.log(arr.copyWithin(0,2,4));//[0,4,0,4,5]
    //参数1表示修改的起始位置,参数2,3表示用来替换的数据的始末位置,左闭右开区间。
    

    fill()用指定的值替换,copyWithin()使用数组中原有的某一部分值替换。

    includes()用于检测数组是否包含某个值,可以指定开始位置。

    let arr = [1,2,3,4,5];
    console.log(arr.includes(2));//true
    console.log(arr.includes(1,1));//false
    

    三、函数

    1,参数默认值

    ES6首次添加了参数默认值。我们再也不用在函数内部编写容错代码了。

    function add(a=1,b=2){
        return a + b;
    }
    add();//3
    add(2);//4
    add(3,4);//7
    

    和参数默认值一起,ES6还带来了不定参。它的功能和使用arguments差不多。

    function add(...num){
        return num.reduce(function(result,value){
            return result + value;
        });
    }
    add(1,2,3,4);//10
    

    下面介绍的箭头函数没有arguments属性,如果箭头函数内要实现不定参,上述方式就是一个不错的选择了。

    2,箭头函数

    箭头函数实现了一种更加简洁的书写方式,并且也解决了关键字声明方式的一些麻烦事儿。箭头函数内部没有arguments,也没有prototype属性,所以不能用new关键字调用箭头函数。

    箭头函数的书写方式:参数 => 函数体。

    let add = (a,b) => {
        return a+b;
    }
    let print = () => {
        console.log('hi');
    }
    let fn = a => a * a;
    //当只有一个参数时,括号可以省略,函数体只有单行return语句时,大括号也可以省略,强烈建议不要省略它们,是真的难以阅读
    

    当函数需要直接返回对象时,你必须使用小括号把对象包裹起来。否则将抛出错误。

    const fn = () =>{name:'ren',age:12};
    // SyntaxError
    *******************************************
    const fn = () =>({name:'ren',age:12});
    

    箭头函数和普通函数最大的区别在于其内部this永远指向其父级AO对象的this。

    普通函数在预编译环节会在AO对象上添加this属性,保存一个对象(请参照《JavaScript之深入对象(二)》)。每个普通函数在执行时都有一个特定的this对象,而箭头函数执行时并不直接拥有this属性,如果你在箭头函数中使用this,将根据函数作用域链,直接引用父级AO对象上this绑定的对象。普通函数的AO对象只有在函数执行时才产生,换言之,普通函数的this是由函数执行时的环境决定。而箭头函数的特别之处在于,当函数被定义时,就引用了其父级AO对象的this,即箭头函数的this由定义时的环境决定。

    根据箭头函数的特点,不难推测:如果定义对象的方法直接使用箭头函数,那么函数内的this将直接指向window。

     var age = 123;
     let obj = {
         age:456,
         say:() => {
             console.log(this.age);
         }
     };
    obj.say();   //123
    //对象是没有执行期上下文的(AO对象),定义对象的方法实际上是在全局作用域下,即window
    

    如果你一定要在箭头函数中让this指向当前对象,其实也还是有办法的(但是没必要这么麻烦啊,直接使用普通函数不是更好吗?):

     var age = 123;
     let obj = {
         age:456,
         say:function(){
             var fn = () => {
             console.log(this.age);
            }
             return fn();
          }
     };
    obj.say();  //456
    

    我们来分析一下这是怎么做到的:首先,我们使用obj调用say方法时,say内创建了AO对象,并且该AO对象的this属性指向了obj(这里不明白的请回去复习一下我的《JavaScript之深入函数/对象》),然后,say内部又声明了一个箭头函数。我们说箭头函数在声明时就要强行引用父级AO的this属性,那么现在该箭头函数的父级AO是谁呢?当然就是say的AO啦,所以这里箭头函数的this直接就绑定了obj,最后箭头函数在执行时拿到的this,实际上就是say方法的AO.this,即obj本身。

    上面是在对象中使用箭头函数,如果那让你难于理解,那么请看下面这种方式:在普通函数中使用箭头函数。

    var obj = {name:'ren'};
    function test(){
        var fn = () => {
            console.log(this);
        };
        fn();
    }
    test();  //window
    test.call(obj);  //{name:'ren'}
    

    test函数在全局执行时,其this指向window,这时也产生了箭头函数的定义,于是箭头函数内的this也被指向了window,所以最终打印出window对象。

    当我们手动改变test函数执行时this的指向时,箭头函数定义所绑定的this实际上也被我们修改了。所以最终打印出obj。

    四、class(类)

    class 作为对象的模板被引入ES6,你可以通过 class 关键字定义类。class 的本质依然是一个函数。

    1,创建类

    class Ex {   //关键字声明方式
        constructor(name){
            this.name = name;
            this.say = () => {
                console.log(this.name);
            }
        }
        methods(){
            console.log('hello ' + this.name);
        }
        static a = 123;
        static m = () => {
            console.log(this.a);
        };
    }
    //let ex = class{}  字面量方式
    var example = new Ex('ren');
    example.say();    //'ren'
    Ex.m();   //123
    example.methods();  //'hello ren'
    
      constructor是创建类必须的方法,当使用new调用类创建实例时,将自动执行该方法,该方法和构造函数类似,默认返回this对象。实例的方法和属性都定义在constructor内部。相当于构造函数的this方式。
    
    
      类保留了prototype属性,类中的方法不需要使用function关键字,并且方法之间不需要逗号隔开。类中定义的方法实际上还是保存在类的prototype属性上。
    
      使用static关键字定义类的静态属性和方法。类中不能定义共有属性,要想定义实例的共有属性还是需要使用prototype属性:Ex.prototype.属性名 = 属性值。
    
      创建实例依然使用new关键字。
    
      2、类的继承
    
      类的继承通过extends关键字实现。
    
    class Person {
        constructor (name,age){
            this.name = name;
            this.age = age;
        }
        say(){
            console.log(this.name + ':' + this.age);
        }
    }
    class Student extends Person{
        constructor (name,age,sex){
            super(name,age);
            this.sex = sex;
        }
    }
    var student = new Student('ren',12,'male');
    student.name;  //'ren'
    student.sex;  //'male'
    student.say();  //'ren:12'
    

    子类继承自父类,不会隐式的创建自己的this对象,而是通过super()引用父类的this。这个过程和在子构造函数内使用父构造函数call(this)很像,但他们有本质的区别。另外,ES6规定,super()必须在子类的this之前执行。所以一般我们把super()放在子类constructor方法的第一行,这样准没错!

    五、模块导入和导出

    1,导入

    ES6使用关键字 import 导入模块(文件),有两种常用的方式:

    import ‘模块名称’ from ‘路径’;
    import  ‘路径’;
    

    通过 import…from 的方式引入模块,模块名称实际上相当于定义一个变量,用来接收即将导入的模块。

    路径可以有很多方式,既可以是绝对路径,也可以是相对路径,甚至只是一个简单的模块名称,更甚至连文件后缀都不需要。当你使用该命令时,系统会自动从配置文件中指定的路径中去寻找并加载正确的文件。

    import Vue from "vue";
    //完整路劲其实是 "../node_modules/vue/dist/vue.js";
    

    通过 import… 的方式一般用来引入样式文件或预处理文件,因为他们不需要用变量来接收。

    2,导出

    ES6 通过 export 和export default 导出模块。导出的含义是向外暴露、输出,在一个文件中通过 import 导入另一个文件,通过变量即可以接收到导出的数据了。一般情况下,JS文件可以向外输出变量、函数和对象。

    let name = 'ren',age = 12;
    export {name,age};
    //注意:变量需要用大括号包裹,然后才能向外输出
    

    如果仅需向外暴露一个变量:

    export var name = 'ren';
    

    使用 export 向外输出函数的用法和变量相同,这里不再举例。

    总结:使用 export 向外输出成员时,可以同时输出多个,并且必须用‘{}’大括号包裹,在其他地方使用 import 导入时,接收成员的变量名必须和这里输出的名称一致,同时,可以根据实际情况,仅接收实际需要的的成员(接收的时候也要用大括号包裹)。

    如果希望通过 export 向外暴露成员,并且在导入的时候自定义接收名称,那么你可以使用 as 关键字重命名。

    let name = 'ren', age = 12;
    export {name, age};
    
    import {name as myName, age as myAge} from 'url';
    

    与 export 相比,export default 有以下几点不同:首先,在同一个模块中,export default 只允许向外暴露一次成员;然后,这种方式可以使用任意的名称接收,不像 export 那样有严格的要求;最后,export 和 export default 可以在同一模块中同时存在。

    let person = {name:'ren'};
    let age = 12;
    let address = 'cd';
    export default person;
    export {age};
    export {address};
    
    import man,{age,address} from 'url'
    

    小技巧:通常 import 无法直接被浏览器识别,即如果在HTML文档中引入的 JS 文件直接使用了 import 关键字,浏览器会报错。要想直接在被HTML文档引用的 JS 文件中使用 import,需要给该

    六  异步机制

    ES6新增了两种实现异步的新机制,Promise和Generator。文笔有限,怕讲的不清楚,误人子弟,请有兴趣的同学去下面的链接继续学习,廖老师的教程也是受很多人推崇的,当然MDN更官方。

    1,Promise

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

    https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544

    2,Generator

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Generator

    https://www.liaoxuefeng.com/wiki/1022910821149312/1023024381818112

    展开全文
  • 为什么是 ES6 模块化规范 ES6 模块化规范是浏览器端与服务器端通用的模块化开发规范。它的出现极大的降低了前端开发者的模块化学 习成本,开发者不需再额外学习 AMD、CMD 或 CommonJS 等模块化规范。 一、ES6 模块...
  • ES6 之前,实现模块化使用的是 CommonJS 和 AMD 两种。前者更适合用于服务器,后者更适合用于浏览器。RequireJS 就是 AMD 最流行的实现...ES6 的模块功能主要由两个命令构成:export 和 import。 export 命令用于规
  • Es6新特性有哪些?

    千次阅读 2020-04-21 09:48:56
    箭头操作符 =>; 对类class的支持(constructor构造函数); 不定参数...x;let和const关键字; ...模块的支持import;...promise异步函数的处理模式(pending等待中;...在ES6中,可以使用解构从数组和对象提取值...
  • 目录 ES5 和 ES6 的区别 ES6 的新增方法 1、新增声明命令 let 和 const 1.1)特点 ...2、模板字符串(Template String) ...6、import 和 export 7、Promise 对象 8、解构赋值 8.1)数组的解构赋值 8.2)
  • ES6之前已经出现了js模块加载的方案,最...ES6模块主要有两个功能:export和import export用于对外输出本模块(一个文件可以理解为一个模块)变量的接口 import用于在一个模块中加载另一个含有export接口的模块。 也就
  • ES6内容1、const 和 let2、箭头函数,箭头函数的this指向3、数组新方法4、模板字符串5、解构赋值6、扩展运算符(... 三个点)和 函数默认值7、class类 和继承8、JSON的应用9、Promise的应用10、async,await组合应用...
  • es6--同步与异步

    2021-08-13 16:43:22
    1 Promise:对异步操作做了一个统一封装。 let p = new Promise((resolve,reject)=>{ $.ajax({ url:"data/a.json", dataType:"json", success(data){ resolve(data); }, err(res){ reject(res) } }) }...
  • es6异步加载

    2018-10-06 11:20:53
    import _ from 'lodash' fetchSuggest: _.debounce(function () {}, 500), 用户输入 在判断 用户连续输入的 情况下 不执行查询操作,一旦用户输入间隔超过500ms 执行查询操作...
  • es6 import()函数

    2021-02-19 14:04:31
    import()函数 简介 前面介绍过,import命令会被 JavaScript 引擎静态分析,先于模块内的其他模块执行(叫做”连接“更合适)。所以,下面的代码会报错。 // 报错 if (x === 2) { import MyModual from './...
  • ES6 import()

    2021-05-26 02:49:53
    前面介绍过,import命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行(import命令叫做“连接” binding 其实更合适)。所以,下面的代码会报错。 // 报错 if (x === 2) { import MyModual from './...
  • ES6 import和export的用法 ES6之前已经出现了js模块加载的方案,最主要的是CommonJS和AMD规范。commonjs主要应用于服务器,实现同步加载,如nodejs。AMD规范应用于浏览器,如requirejs,为异步加载。同时还有CMD规范...
  • ES6 新增特性有那些?

    2021-06-03 00:28:31
    ES6新增了许多新特性,不是因为面试经常会问才需要会它,个人认为里面的许多方法特别简单 下面是我整理的一些比较常用的新增特性 一、新增数据类型 Symbol 猿话:Symbol-ES6神奇的数据类型​zhuanlan.zhihu....
  • ES6设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量 // ES6模块 import { stat, exists, readFile } from 'fs'; 上述代码,只加载3个方法,其他方法不加载,即 ES6 可以...
  • ### 1、概述 一直以来开发vue项目,对export和import的用法都比较模糊,看别人怎么写...为此ES6新增了export和import命令实现了模块功能,而且它的实现方式简单得不可思议,完全取代了CommonJS和AMD,现已成为浏览...
  • 第一次执行node的es6模块化 (1)确保node版本,14.15.1以上 node -v (2)生成package.json npm init -y (3)修改package.json "type":"module", 注意:如果是中文有空格的路径文件夹,那么手动创建package.json (4)写代码 ...
  • CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。 CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。...CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载
  • ES6 import和Node require

    2019-05-22 16:54:06
    ES6之前已经出现了js模块加载的方案,最主要的是CommonJS和AMD规范。commonjs主要应用于服务器,实现同步加载,如nodejs。AMD规范应用于浏览器,如requirejs,为异步加载 require的基本语法 核心概念:在导出的...
  • ES6 模块是动态引用,如果使用 import 从一个模块加载变量,那些变量不会缓存,而是成 为 一个指向被加载模块的引用,import/export 最终都是编译为 require/exports 来执行的 require/exports来自野生规范当中,即...
  • 之前一直搞不懂export、export defalut、import之间的关系,总是模模糊糊靠猜,认真学习了下,现在我又行了
  • ES6模块化与异步编程

    2021-08-01 15:39:48
    1ES6模块化 2Promise 3asycn/await 4EventLoop 5宏任务与微任务 6数据库API接口 1ES6模块化 其实以前的文章也涉及到过ES6点的相关知识,但是总结的不算太完全,并且并没有深刻的认识。所以我又重新对知识点...
  • ES6模块化与异步编程学习笔记
  • 文件结构: 导出:export_0.js let myName = "Tom"; let myAge = 20; let myfn = function(){ return "My name is" + myName + "! I'm '" + myAge + "years old." ...let myClass = class myClass { ...导入:es6.

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,332
精华内容 7,332
热门标签
关键字:

ES6 import 是异步的么?