一. for of
在最开始20年前,javascript刚出来的时候我们用的是 for循环
for(var i=0; i< myArr.length; i++) {
console.log(myArr[i])
}
从ES5出来之后我们喜欢用 forEach 来循环数组
myArr.forEach(function (value) {
console.log(value)
})
当然你在forEach中不能使用break,也不能使用return 返回到外层函数,这是一个小小的缺陷
当然也有我们熟悉的 for in
for(var index in myArr) {
conosle.log(myArr[index])
}
对于这个,其中要注意一点, index 并不是纯粹的数字,而是 字符 “0” ,“1”, “2” 所以千万别直接相加 ,否者 会出现 “1” + 2 = “12” 的结果
好了,废话不多少,让我们看看 ES6中, for of的强大吧
// 支持数组
for (var value of myArr) {
console.log(value)
}
// 也支持字符串
for(var value of "abcdef") {
console.log(value)
}
// 在ES6 中,同样我们也有 Set() 和 Map() 方法
// Set对象可以自动排除重复项
let arr = [1,2,3,4,1,2];
let arr1 = new Set(arr);
let arr2 = [];
for (let item of arr1) {
arr2.push(item);
}
console.log(arr2); // 結果是 => [1,2,3,4]
// Map 则稍有不同,它是由键值对 来组成的
for (var [key, value] of bookMap) {
console.log("key: " + key + ",value: " + value)
}
// 同样他也可以拿到枚举对象
for (var key of Object.keys(object)) {
console.log("key: " +key + ", value: " + object[key])
}
二: 生成器
众所周知,在一个函数里面,就只能拿到一个return的值,但是在生成器里面有一种类似于return的语法,yield 可以多次,就是在生成器里面遇到yield就会暂停,后续可恢复执行状态.
// 生成器和普通函数的区别就是多了一个*号
function* cat(name) {
yield "你好: " + name
yield "希望你能喜欢这篇文章!"
yield "谢谢你,我们下次再见."
}
// 现在我们来执行一下这个代码
var item = cat("小白");
item.next(); // {value: "你好: 小白", done: false}
item.next() // {value: "希望你能喜欢这篇文章!", done: false}
item.next() // {value: "谢谢你,我们下次再见.", done: false}
item.next() // {value: undefined, done: true}
当你调用next() 时,他就自己解冻并执行,直到遇到下一个yield,再次暂停.
当我们执行到最后一个next() 时,函数到达末尾,意味着没有返回值,所以value返回的是undefined
三. 模板字符串 `` (window + ~ 打出)
模板字符串就是简化了以前的拼接字符串
例如:
var cat = "小白";
var color = "白色";
// 传统的则需要
var result = cat + "是一个" + color + "的猫";
// ES6模板字符串,变量需要${}包含起来,才能解析出来
var es6Result = `${cat}是一个${color}的猫`;
四. 不定参数…
传统函数
function cat(name, color, status) {
console.log(`${name}是一个${color}的猫,现在正在${status}老鼠`)
}
//如果我们不写参数就会报undefined,没有找到
cat(); // undefined是一个undefined的猫,现在正在undefined老鼠
cat("小白", "白色", "追"); // 小白是一个白色的猫,现在正在追老鼠
那如果我们不知道参数,该写多少个,那么我们就有了下面的方法
function cat(...parameters) {
for (let value of parameters) {
console.log("value: " + value)
}
}
cat("小白", "小黑") //value: 小白 value: 小黑
cat("小白", "小黑", "白色", "黑色") //value: 小白 value: 小黑 value: 白色 value: 黑色
当然我们还可以用到数组中
//es6 用法
let [a,b] = [3,4]; //结果是 a=3 b=4
let [a,...b] = [3,4,5,6] // 结果是a=3 b=[4,5,6]
let [a,b,c] = "ES6"; //结果是 a=E b=S c=6
let xy = [...'ES6'] //结果是 ['E', 'S', '6']
五. {} 解构特性的使用
在函数中,我们为了方便API的使用,不想记住参数的位置,那么便出现了下面一种写法
function ({url, line, column}) {
...
}
var obj = {
name: "蜜蜂",
status: "飞行"
}
// 我们可以通过这种方式来拿到值, 也是比较推荐的一种写法
const { name, status } = obj;
console.log(name) // 蜜蜂
console.log(status ) // 飞行
六. 箭头函数
//传统写法
function cat(name, color) {
return `${name}是${color}的猫`
}
//箭头函数没有自己的this值,箭头函数内的this继承与他的外围函数的作用域
let cat = (name, color) => {
return `${name}是${color}的猫`
}
//是不是方便了很多
//没有参数 写法 let cat = () => {}
//1个参数 写法 let cat = name => {}
//2个参数 写法 let cat= (name, color) => {}
七. import 和 export的使用,当然介绍道这里,我们就可以把AMD,CMD, CommonJs(只是简单的说一下,有需要的可以自己查阅官网),就可以一起拿来,毕竟他们都是对模块的定义
AMD 是基于RequireJs 在推广过程中对模块的定义,异步加载的东西
//['package.lib'] 是代表它所以依赖的库
define(['package.lib'], function () {
function foo() {
lib.log('hello world!')
}
return {
foo: foo
}
})
CMD 是基于SeaJs 在推广过程中对模块的定义,淘宝团队开发的
// 所有模块都通过 define 来定义
define(function(require, exports, module) {
// 通过 require 引入依赖
var $ = require('jquery');
var Spinning = require('./spinning');
// 通过 exports 对外提供接口
exports.doSomething = ...
// 或者通过 module.exports 提供整个接口
module.exports = ...
});
CommonJs , 一般不用于前端开发,只是后台nodejs用的比较多
exports.cat= function (name, color) {
return `${name}是${color}的猫`;
}
现在我们的import和export来了
//export 的用法 文件名叫cat.jsx
export default {
name: "小白",
color: "白色"
}
//那么我们import 引入, 比如在同一目录下
import cat from "./cat.jsx";
//使用方法
cat.name // 小白
cat.color // 白色
//当然 我么也可以export 方法 文件名是animal.jsx
export const cat = (name, color) => {
console.log(`${name}是${color}的猫`)
}
export const dog = (color) => {
console.log(`狗是${color}`)
}
// import 引入方法
import animal from "./animal.jsx" //使用方法 animal.dog("白色")
import { cat, dog } from "./animal.jsx" //使用方法 dog("白色")
import * as animal from "./animal.jsx" //使用方法 animal.dog("白色")
//简单来说 animal 其实的原理就是 (* as animal)
八. class 类的用法
传统方法
function Circle(radius) {
this.radius = radius;
Circle.circleMade++;
}
Circle.draw = function draw() {
Object.defineProperty(Circle, "circleMade", {
get: function () {
return !this._count ? 0: this._count;
},
set: function (val) {
this._count = val;
}
})
}
//Circle 的原型链赋值
Circle .prototype = {
area () {
return Math.pow(this.radius, 2) * Math.PI;
}
get radius() {
return this.radius;
}
set radius(radius) {
this.radius = radius
}
}
虽然这个样子已经都好了,但是我们有没有一种方法,就是在定义时就拿到获取到他的属性,结果是当然有的
代码如下
class Circle {
constructor(radius) {
this.radius = radius;
Circle.circleMade++;
}
static draw () {
Object.defineProperty(Circle, "circleMade", {
get: function () {
return !this._count ? 0: this._count;
},
set: function (val) {
this._count = val;
}
})
}
static get circleMade() {
return !this._count ? 0: this._count;
}
static set circleMade(val) {
this._count = val;
}
area () {
return Math.pow(this.radius, 2) * Math.PI;
}
get radius() {
return this.radius;
}
set radius(radius) {
this.radius = radius
}
}
// **super() 属性**
子类可以继承父类的属性,那么我们子类和父类有相同的属性名怎么办,怎么解决这个问题呢
super 可以绕开我们在子类中定义的属性,直接从原型上开始查找,从而绕过我们覆盖父类同名的方法
class Circle {
constructor(props) {
super(props);
...
}
...
}
九. let 和 const
let是作用域块级作用域,就是只作用于它所在的模块,可以这么说,let是更完美的var
代码如下
//let 只可以定义一个, 而var 则可以定义多个
let a = 1;
let a = 2;
var b = 3;
var b = 4;
a // Identifier 'a' has already been declared
b // 4
//for 循环计数器很适合用 let
// 输出十个 10,为什么会输出10个10呢,为什么不是9呢,因为他们的var 都指向同一个this,等程序结束完之后,它们的定时器就一起输出
for (var i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i);
})
}
// 输出 123456789
for (let j = 0; j < 10; j++) {
setTimeout(function(){
console.log(j);
})
}
//const 用法 ,一般用来指定不变的字符,如果给同一个变量再次赋值,那么就会报错
const cat = "小白";
cat // "小白"
const cat = "小黑"; //Identifier 'cat ' has already been declared
好了,大概常用的ES6语法 都应该在这里了,如果有任何问题,欢迎指出,一起进步,谢谢.