Ecmascript 6解构赋值及扩展

Ecmascript 6

  • ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。
  • Ecmascript 是 JavaScript 语言的标注规范
  • JavaScript 是 Ecmascript 规范的具体实现
    • 具体实现取决于各大浏览器厂商的支持进度
  • Ecmascript 6 也被称作 Ecmascript 2015
  • 各大浏览器厂商对于最新的 Ecmascript 6 标准支持可以参照:
  • 对于不支持 ES6 的环境,可以使用一些编译转码工具做转换处理再使用
    • 例如 babel

let 和 const

  • let 类似于 var,也是用来定义变量的
  • 通过 let 定义的变量是块级作用域,只在当前代码块有效
  • const 也类似于 var,用来定义常量
  • 通过 const 定义的常量,定义的时候必须初始化
  • const 定义的变量一旦定义,不能修改
  • let 和 const 都没有作用域提升
  • let 和 const 在一个块级作用域中都不能重复定义

解构赋值

数组解构:

let [a, b, c] = [123, 456, 789]
console.log(a, b, c) //123 456 789

方法:

// 将一个伪数组转为一个真正的数
Array.from()

// Array.of方法用于将一组值,转换为数组
Array.of()

// 查找某个元素
Array.find()

// 查找某个元素的索引下标
Array.findIndex()

对象解构:

let { name, age } = { name: 'Jack', age: 18 }
console.log(name, age)// Jack 18

函数参数解构:

function f (p1, { p2 = 'aa', p3 = 'bb' }) {
  console.log(p1, p2, p3)
}

f('p1', { p2: 'p2' })// p1 p2 bb
var obj = { a :"aaa", b:"bbb" }
    var { b } = obj
    console.log(b)//bbb

字符串解构:

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

方法: includes startsWith endsWith repeat 模板字符串:凡是以后需要字符串拼接的地方都使用模板字符串 如果是普通的字符串,就还是通过原来的 单引号 去定义

扩展

数组的扩展

 //array.find()寻找某个元素和 array.findIndex()寻找某个值的下标
     const arr = [
       { foo: 'a', name: 'aaa' },
       { foo: 'b', name: 'bbb' },
       { foo: 'b', name: 'bbc' },
       { foo: 'c', name: 'ccc' },
     ]
    var item1 = arr.find(function(obj,index){
       return obj.foo === 'b'
    })
     var item2 = arr.findIndex(function(obj,index){
         return obj.foo === 'c'
     })
    console.log(item1) //{foo :'b',name:'bbb'}
    console.log(item2)//3

     //array.keys()遍历数组下标
     let arr1 = ['a', 'b', 'c']
     console.log(arr1.keys());
     for(let index of arr1.keys()){
         console.log(index);// 0 1 2
     }
     //不支持array.values()这个方法
     for(let index of arr1.values()){
         console.log(index);//报错
     }
    //array.entries()遍历数组
     for(let [index,item] of arr1.entries()){
         console.log(index);//0 1 2
         console.log(item);// a b c
     }
    // 是否包含某个元素
     console.log(arr1.includes('d'))//false
     console.log(arr1.includes('a'))//true

字符串的扩展

let name = 'Jack'
    let foo = `hello ${name} haha
               大家好,我叫:${name}
               调用函数:${f()}`

    console.log(foo)

    function f() {
        return 'hello'
    }
输出:
hello jack haha
大家好,我叫: jack
调用函数: hello

函数的扩展

// 默认值最好作为函数的最后一个参数
// 如果是前面的参数默认值,则不能省略,不能跳过
function f(x = 20, y = 10) {
  console.log(x, y)
}
f()// 20,10

// ...args 叫做 rest 参数
// ...args 是一种语法,...不能省略,args 是随便起的一个名字
// ...args 可以将用户传递进来的参数包装到一个数组中
// ...args 是把用户传递参数的没有对应到具体形参的变量解析到一个数组中
function f(a, ...args) {
  let sum = 0
  for(let num of args) {
    sum += num
  }
  console.log(sum)
}
f(1, 2, 3)//2+3 = 5



// ... 扩展运算符,可以将一个数组展开
let arr = [1, 2, 3]
console.log(...arr)// 1 2 3

let arr1 = [1,2]
let arr2 = [3,4]
let result = [...arr1, ...arr2]
console.log(result)//[1,2,3,4]

function f1(x, y, z) {
  console.log(x, y, z)//1,2,3
}

var arr = [1, 2, 3]
f1.apply(null, arr)
f1(...arr)
补充apply 和call 的区别
apply
函数名.apply(obj, 数组or伪数组);
功能:
   -1. 调用函数
   -2. 改变this指向为第一个参数中的对象
   -3. 将第二个参数的数组或者伪数组,中的元素一一拆解,依次传递给函数作为实参

call
函数名.call(obj, arg1...argN);
功能:
   -1. 调用函数
   -2. 改变this指向为第一个参数中的对象
   -3. 将第二个及以后的所有参数,依次的传递给函数作为实参
注意事项:
-如果call和apply的第一个参数为null或者undefined,this将会指向window
-如果call和apply的第一个参数为值类型的数据,会将值类型的数据转换成其对应的引用类型的数据,this指向该引用类型的数据
tips: 一般情况下apply的传参特性会被使用的居多(转换伪数组为真数组,求最大值)

call , apply实现继承

function  Person(name,age,love){  
        this.name=name;  
        this.age=age;  
        this.love=love;  
        this.say=function say(){  
            alert("姓名:"+name);  
        }  
    }  

    //call方式  
    function student(name,age){  
        Person.call(this,name,age);  
    }  

    //apply方式  
    function teacher(name,love){  
        Person.apply(this,[name,love]);  
        //Person.apply(this,arguments); //跟上句一样的效果,arguments  
    }

对象的扩展

// 对象属性成员的 get 和 set 方法适合做一些数据合法性校验
var xiaoming = {
    name: 'lemon_zoey',
    _age: 20,
    get age () {
        return this._age
    },

    set age (value) {
        if (value < 0 || value > 100) {
            throw new Error('这个数据不合法哦')
        }
        this._age = value
    }
}

 console.log(xiaoming.age)//20
 console.log(xiaoming._age)//20

 xiaoming.age = -1

 console.log(xiaoming.age)//Uncaught Error: 这个数据不合法哦

// 获取一个对象所有键名数组
console.log(Object.keys(xiaoming))//name _age age

箭头函数

let f = function (v) {
     return v
  }
//等价于
let f = v => v

//如果有多个参数,必须加括号
 let  fn = (x, y) => x + y

// 如果方法体有多条执行语句,则必须加 {}
let add = (x, y) => {
  console.log(x, y)
  return x + y
}

// 箭头函数最好都用在匿名函数的地方
let arr = [1, 2, 3]
arr.forEach(n => console.log(n))
let newArr = arr.map(n => n + 1)
console.log(newArr)

 // 函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象
function Person({ name = 'Jack', age = 18 }) {
   this.name = name
   this.age = age
 }
 Person.prototype.sayHello = function () {
   setTimeout(() => {
     console.log(`hello name: ${this.name}, age: ${this.age}`)
   }, 1000)
 }
 var p1 = new Person({})
 p1.sayHello() //hello name: jack,age: 18

// 不能作为构造函数使用
let F = (x, y) => {
    return x + y
}
var f = new F(10, 20)// Uncaught TypeError: F is not a constructor

module

const fs = require('fs')
//Equivalent to
import fs from 'fs'

模块加载的不同种类

在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种,CommonJS 模块就是对象,输入时必须查找对象属性。

// CommonJS模块
let { stat, exists, readFile } = require('fs');

// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;
  • ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。
// ES6模块
import { stat, exists, readFile } from 'fs';

模块加载的好处。

  • 静态加载带来的各种好处,效率高于common.js
  • 不再需要UMD模块格式了,将来服务器和浏览器都会支持 ES6 模块格式。
  • 将来浏览器的新 API 就能用模块格式提供,不再必须做成全局变量或者navigator对象的属性。 不再需要对象作为命名空间(比如Math对象),未来这些功能可以通过模块提供。

export

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

// profile.js
export var name= 'lemon_zoey';
export var age = '20'
//Equivalent to
var name = 'lemon_zoey'
export {name,age}

export命令除了输出变量,还可以输出函数或类(class)。

export function fn(a,b){
}

需要特别注意的是,export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系

// 报错,没有提供对外的接口
export 1;

// 报错,没有提供对外的接口
var m = 1;
export m;

//正确写法,它们的实质是,在接口名与模块内部变量之间,建立了一一对应的关系
// 写法一
export var m = 1;

// 写法二
var m = 1;
export {m};

// 写法三
var n = 1;
export {n as m};

import

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

import {firstName, lastName, year} from './index';

整体加载*

下面是一个index.js文件,它输出两个方法fn1和fn2。

// index.js

export function fn1(a) {
  return a
}

export function fn2(b) {
  return b
}

现在,加载这个模块

//main.js
import { fn1, fn2} from './index';//逐一加载
//Equivalent to
import  * as  index from './index'
console.log(index.fn1)//a

export default 命令

// export-default.js
export default function () {
  console.log('foo');
}
// import-default.js
import customName from './export-default';
customName(); // 'foo'
//需要注意的是,这时import命令后面,不使用大括号。

注意:export 与 import 对应的需要加{} export default 与 import对应的不需要加{}

转载于:https://my.oschina.net/u/3305487/blog/1154129

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值