| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> JavaScript知识库 -> JavaScript ES6新特性介绍 -> 正文阅读 |
|
[JavaScript知识库]JavaScript ES6新特性介绍 |
JavaScript ES6新特性介绍ES6是一次重大的革新,比起过去的版本,改动比较大。ECMAScript 2015(ES2015),第 6 版,也被称作是 ECMAScript 6(ES6),添加了类和模块的语法,箭头函数,迭代器和生成器和生成器表达式,静态类型数组等 let、const 在ES6以前,JS只有var一种声明方式,且存在变量提升现象,但是在ES6之后,就多了let跟const这两种方式。用var定义的变量没有块级作用域的概念,而let跟const则会有,它们的区别如下表:
【注:暂时死区 由于let/const没有变量提升(提升到作用域顶部),因此通过let/const定义的变量不会被提升到作用域顶部——也就是此时的块级作用域,因此在声明之前无法访问——若在声明之前使用将报错。】 let 关键词声明的变量不具备变量提升(hoisting)特性, let 和 const 声明只在最靠近的一个块中(花括号内)有效, const 在声明时必须被赋值。 ES6推荐使用let声明局部变量,相比之前的var(无论声明在何处,都会被视为声明在函数的最顶部) let和var声明的区别: var x = '全局变量'; { ? let x = '局部变量'; ? console.log(x); // 局部变量 } console.log(x); // 全局变量 let表示声明变量,而const表示声明常量,两者都为块级作用域;const 声明的变量都会被认为是常量,意思就是它的值被设置完成后就不能再修改了: const x = 10 a = 20 //报错 如果const的是一个对象,对象所包含的值是可以被修改的。抽象一点儿说,就是对象所指向的地址没有变就行: const student = { name: 'LiMing' } student.name = 'ZhangHua';// 不报错 student? = { name: 'ZangHua' };// 报错 关于let声明语句,参见: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let const声明语句,参见: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/const 类(Class) 在ES6之前,如果我们要生成一个实例对象,传统的方法就是写一个构造函数,例子如下: function Person(name, age) { ??? this.name = name ??? this.age = age } Person.prototype.information = function () { ??? return 'My name is ' + this.name + ', I am ' + this.age } 但是在ES6之后,我们只需要写成以下形式: class Person { ??? constructor(name, age) { ??????? this.name = name ??????? this.age = age ??? } ??? information() { ??????? return 'My name is ' + this.name + ', I am ' + this.age ??? } } 关于类,可参见: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes 箭头函数(Arrow Functions) ES6 中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体; ES6 中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体; 早期的函数,如: let add=function(a,b){ ??? return a+b; }; 用箭头函数,可写为为: let add=(a,b)=>a+b; 箭头函在数语法上要比普通函数简洁得多。箭头函数省去了function关键字,采用箭头=>来定义函数。函数的参数放在=>前面的括号中,函数体跟在=>后的花括号中。 箭头函数最直观的三个特点: 不需要 function 关键字来创建函数; 省略 return 关键字; 继承当前上下文的 this 关键字。 关于箭头函数的参数的说明: ① 如果箭头函数没有参数,直接写一个空括号即可。 ② 如果箭头函数的参数只有一个,也可以省去包裹参数的括号。 ③ 如果箭头函数有多个参数,将参数依次用逗号(,)分隔,包裹在括号中即可。 // 没有参数 let fun1 = () => { ??? console.log(123); }; // 只有一个参数,可以省去参数括号 (name) let fun2 = name => { ??? console.log(`Hello ${name} !`) }; // 有多个参数 let fun3 = (val1, val2, val3) => { ??? return [val1, val2, val3]; }; 关于箭头函数的函数体的说明: ① 如果箭头函数的函数体只有一句代码,就是简单返回某个变量或者返回一个简单的JS表达式,可以省去函数体的大括号{ }。 let f = val => val; // 等同于 let f = function (val) { return val }; let sum = (num1, num2) => num1 + num2; // 等同于 let sum = function(num1, num2) { ? return num1 + num2; }; ② 如果箭头函数的函数体只有一句代码,就是返回一个对象,可以像下面这样写: // 用小括号包裹要返回的对象,不报错 let getTempItem = id => ({id: id, name: "Temp"}); // 但绝不能这样写,会报错。 // 因为对象的大括号会被解释为函数体的大括号 let getTempItem = id => {id: id, name: "Temp"}; ③ 如果箭头函数的函数体只有一条语句并且不需要返回值(最常见是调用一个函数),可以给这条语句前面加一个void关键字 let fn = () => void doesNotReturn(); 箭头函数与普通函数的区别 箭头函数与普通函数的区别 ①箭头函数不绑定this关键字,箭头函数没有自己的this关键字,箭头函数中的this指向的是函数定义位置的上下文this,换句话说,箭头函数没有自己的this,它会捕获自己在定义时(注意,是定义时,不是调用时)所处的外层执行环境的this,并继承这个this值。所以,箭头函数中this的指向在它被定义的时候就已经确定了,之后永远不会改变。 var id = 'Global'; function fun1() { ??? // setTimeout中使用普通函数 ??? setTimeout(function(){ ??????? console.log(this.id); ??? }, 2000); } function fun2() { ??? // setTimeout中使用箭头函数 ??? setTimeout(() => { ??????? console.log(this.id); ??? }, 2000) } fun1.call({id: 'Obj'});???? // 'Global' fun2.call({id: 'Obj'});???? // 'Obj' 上面这个例子,对象obj的方法a使用普通函数定义的,普通函数作为对象的方法调用时,this指向它所属的对象。所以,this.id就是obj.id,所以输出'OBJ'。 但是方法b是使用箭头函数定义的,箭头函数中的this实际是继承的它定义时所处的全局执行环境中的this,所以指向Window对象,所以输出'GLOBAL'。 并且,箭头函数继承而来的this指向永远不变! 上面的例子,就完全可以说明箭头函数继承而来的this指向永远不变。对象obj的方法b是使用箭头函数定义的,这个函数中的this就永远指向它定义时所处的全局执行环境中的this,即便这个函数是作为对象obj的方法调用,this依旧指向Window对象。 ②箭头函数不能作为构造函数使用(不能用new) 先了解一下构造函数的new都做了些什么?简单来说,分为四步: 1)JS内部首先会先生成一个对象; 2)再把函数中的this指向该对象; 3) 然后执行构造函数中的语句; 40 最终返回该对象实例。 因为箭头函数没有自己的this,它的this其实是继承了外层执行环境中的this,且this指向永远不会随在哪里调用、被谁调用而改变,所以箭头函数不能作为构造函数使用,或者说构造函数不能定义成箭头函数,否则用new调用时会报错! let Fun = (name, age) => { ??? this.name = name; ??? this.age = age; }; // 报错 let p = new Fun('cao', 24); ③箭头函数没有自己的arguments 箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是外层局部函数执行环境中的值。可以在箭头函数中使用rest参数代替arguments对象,来访问箭头函数的参数列表! ES6引入 rest参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。 关于剩余参数,参见 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters ④箭头函数不能使用yeild关键字,因此箭头函数不能用作Generator函数。 关于箭头函数,可参见: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions 迭代器(Iterator)和生成器(Generator) 下面是一段标准的for循环代码,通过变量i来跟踪colors数组的索引,循环每次执行时,如果i小于数组长度len则加1,并执行下一次循环 下面是一段标准的for循环代码,通过变量i来跟踪a数组的索引,循环每次执行时,如果i小于数组长度len则加1,并执行下一次循环 let a = ["aaa","bbb","ccc"]; for (let i = 0; i< a.length; i++){ ??? console.log(a[i]); } i就是我们用来记录迭代位置的变量,但是在ES6开始,JavaScrip引入了迭代器这个特性,迭代器的出现旨在消除这种复杂性并减少循环中的错误,并且新的数组方法和新的集合类型(如Set集合与Map集合)都依赖迭代器的实现,这个新特性对于高效的数据处理而言是不可或缺的,在语言的其他特性中也都有迭代器的身影:新的for-of循环、展开运算符(...),甚至连异步编程都可以使用迭代器。 迭代器是一种特殊对象,它具有一些专门为迭代过程设计的专有接口,所有的迭代器对象都有一个next()方法,每次调用都返回一个结果对象。结果对象有两个属性:一个是value,表示下一个将要返回的值;另一个是done,它是一个布尔类型的值,当没有更多可返回数据时返回true。 生成器是一种返回迭代器的函数,通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield。星号可以紧挨着function关键字,也可以在中间添加一个空格,例如: // 生成器 function *createIterator() { ??? yield 1; ??? yield 2; ??? yield 3; } // 生成器能像正规函数那样被调用,但会返回一个迭代器 let iterator = createIterator(); console.log(iterator.next().value); // 1 console.log(iterator.next().value); // 2 console.log(iterator.next().value); // 3 示例中,createlterator()前的星号表明它是一个生成器;yield关键字也是ES6的新特性,可以通过它来指定调用迭代器的next()方法时的返回值及返回顺序。生成迭代器后,连续3次调用它的next()方法返回3个不同的值,分别是1、2和3。 在生成器函数中,每当执行完一条yield语句后函数就会自动停止执行,在上面这段代码中,执行完语句yield 1之后,函数便不再执行其他任何语句,直到再次调用迭代器的next()方法才会继续执行yield 2语句。 关于迭代器(Iterator)和生成器(Generator),简要介绍这些,想了解更多,可参见: https://www.cnblogs.com/xiaohuochai/p/7253466.html https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Iterators_and_Generators 待续 |
|
JavaScript知识库 最新文章 |
ES6的相关知识点 |
react 函数式组件 & react其他一些总结 |
Vue基础超详细 |
前端JS也可以连点成线(Vue中运用 AntVG6) |
Vue事件处理的基本使用 |
Vue后台项目的记录 (一) |
前后端分离vue跨域,devServer配置proxy代理 |
TypeScript |
初识vuex |
vue项目安装包指令收集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 | -2025/3/4 8:16:35- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |