ES6 简易示例

2022-03-04  本文已影响0人  wyc0859

Map对象

Map对象 和 Objects 的区别
Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
一个 Object 的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值。
get 和 set方法

const print = console.log
var map1 = new Map()
var keyString = 'a string'
map1.set(keyString, "和键'a string'关联的值")
const a1 = map1.get(keyString) // "和键'a string'关联的值"
const a2 = map1.get('a string') // "和键'a string'关联的值"
//print('a1-2:', a1, a2)

Set对象

Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。
add方法

let mySet = new Set()
mySet.add(1) // Set(1) {1}
mySet.add(5) // Set(2) {1, 5}
mySet.add(5) // Set(2) {1, 5} 这里体现了值的唯一性
mySet.add('some text') // Set(3) {1, 5, "some text"} 这里体现了类型的多样性

var o = { a: 1, b: 2 }
mySet.add(o) //Set(4) { 1, 5, 'some text', { a: 1, b: 2 } }
//console.log(mySet)
mySet.add({ a: 1, b: 2 }) // Set(5) { 1, 5, 'some text', { a: 1, b: 2 }, { a: 1, b: 2 } }
// 这里体现了对象之间引用不同不恒等,即使值相同,Set 也能存储

解构

//数组解构
let [a, b, c] = [1, 2, 3] // a = 1  b = 2  c = 3 
let [e, , g] = [1, 2, 3] // e = 1  g = 3 

//对象解构
let { foo, bar } = { foo: 'aaa', bar: 'bbb' } // foo = 'aaa'  bar = 'bbb' 

//注意下面不是逗号,是冒号
let { x: y } = { x: 'x1' }   // y='x1'
let { v: w } = { vv: 'v1' } // undefined
// console.log(y) //打印x会报错  x1
// console.log(w) //打印v会报错  undefined

Proxy

可以对目标对象的读取、函数调用等操作进行拦截,然后进行操作处理。它不直接操作对象,而是像代理模式,通过对象的代理对象进行操作,在进行这些操作时,可以添加一些需要的额外操作。
一个Proxy对象由两个部分组成,构造函数生成实例需target目标对象 和 handler对象(声明代理target的指定行为)
get 、 set、 construct、 has

let target = {
  name: 'Tom',
  age: 20
}
let handler = {
  get: (target, key) => {
    console.log('get: ' + key)
    return target[key] // 不是target.key
  },
  set: (target, key, value) => {
    console.log('set: ' + key)
    target[key] = value
  }
}
let proxy = new Proxy(target, handler)
  //console.log(target, proxy) //2个相等 { name: 'Tom', age: 20 } { name: 'Tom', age: 20 }
  proxy.name // 实际执行 handler.get  //打印get: name
  proxy.age = 25 // 实际执行 handler.set  //打印set: age

通过构造函数新建实例时其实是对目标对象进行了浅拷贝,因此目标对象与代理对象会互相影响


Reflect

可以用于获取目标对象的行为,它与 Object 类似,但是更易读,
为操作对象提供了一种更优雅的方式。它的方法与 Proxy 是对应的
get 、 set、 construct、 has

 //Reflect.get(target, name, receiver)
    let exam = {
      name: 'Tom',
      age: 24,
      get info() {
        return this.name + this.age
      }
    }
    const res = Reflect.get(exam, 'name')
    //console.log('res:', res) //res: Tom

    // 当target对象中存在name属性的getter方法,getter方法的this会绑定,参数3:obj
    let obj = {
      name: 'Jerry',
      age: 20
    }
    const r0 = Reflect.get(exam, 'info') // Tom24
    const r1 = Reflect.get(exam, 'info', obj) // Jerry20
    // 当 name 为不存在于 target 对象的属性时,返回 undefined
    const r2 = Reflect.get(exam, 'birth') // undefined
    //const r3 = Reflect.get(1, 'name') // 会报错,因为target不是对象 

字符串

includes和模板字符串

  const print = console.log 
  let string = 'apple,banana,orange'
  print(string.includes('banana')) // true  判断是否找到参数字符串
  print(string.startsWith('apple')) // true  判断参数字符串是否在原字符串的头部
  print(string.endsWith('apple')) // false  判断参数字符串是否在原字符串的尾部  

这三个方法只返回布尔值,如果需要知道子串的位置,还是得用 indexOf

模板字符串:字符串插入变量、表达式、调用函数

  let namea = 'Mike'
  let age = 27
  let info = `My Name is ${namea},I am ${age + 1} years old next year.` 
 
  function f() {
    return 'have fun!'
  }
  let string2 = `Game start,${f()}`
  console.log(string2) // Game start,have fun!

对象object

Object.assign() 与 Object.is()

let age = { age: 15, city: 'beijing' }
let names = { names: 'Amy', age: 18 } 
let person2 = { ...age, ...names } //{ age: 18, city: 'beijing', names: 'Amy' } 同名的属性将被覆盖掉

Object.assign(target, source_1, ···)
用于将源对象的所有可枚举属性复制到目标对象中。

let target = { a: 1 }
let object2 = { b: 2 }
let object3 = { c: 3 }
Object.assign(target, object2, object3) // 第一个参数是目标对象,后面的参数是源对象
console.log(target) //{ a: 1, b: 2, c: 3 }

target = { ...target, ...object2, ...object3 }
console.log(target) //{ a: 1, b: 2, c: 3 }

//如果该函数只有一个参数,当参数为对象时,直接返回该对象;
//当参数不是对象时,会先将参数转为对象然后返回。
const objx = Object.assign(3)
console.log(objx, typeof objx) // [Number: 3] object

Object.is(value1, value2) 用来比较两个值是否严格相等,与(===)基本类似。

Object.is('q', 'q') // true
Object.is(1, 1) // true
Object.is([1], [1]) // false
Object.is({ q: 1 }, { q: 1 }) // false

数组

Array.of()、Array.from()

  console.log(Array.of(1, 2, 3, 4)) // [1, 2, 3, 4]
  console.log(Array.of(1, '2', true)) // [1, '2', true] // 参数值可为不同类型
  console.log(Array.of()) // [] // 参数为空时返回空数组

Array.from() 将类数组对象或可迭代对象转化为数组。

console.log(Array.from([1, 2])) // [1, 2]  参数为数组,返回与原数组一样的数组
console.log(Array.from([1, , 3])) // [1, undefined, 3] 参数含空位

//第2可选参数:map 函数、第3可选参数:thisArg(用于指定 map 函数执行时的 this 对象)
let map = {
  do: (n) => {
    return n * 2
  }
}
let arrayLike = [3, 4, 5]
const res = Array.from(
  arrayLike,
  function (n) {
    return this.do(n)
  },
  map
)
console.log(res) // [ 6, 8, 10 ]

类"数组对象" 转数组
一个类数组对象必须含有 length 属性,且元素属性名必须是数值或者可转换为数值的字符。

let arr = Array.from({
  0: '1',
  1: '2',
  2: 3,
  length: 3
})
console.log(arr) // ['1', '2', 3]

map转数组、set转数组、字符串转数组

let map = new Map()
map.set('key0', 'value0')
map.set('key1', 'value1')
console.log(Array.from(map)) // [['key0', 'value0'],['key1', 'value1']]
 
let arr = [1, 2, 3]
let set = new Set(arr)
console.log(Array.from(set)) // [1, 2, 3]
 
let str = 'abc'
console.log(Array.from(str)) // ["a", "b", "c"]

函数

箭头函数有几个使用注意点。
(1)箭头函数没有自己的this对象
(2)不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数

对于普通函数来说,内部的this指向函数运行时所在的对象

var Person = {
  age: 18,
  sayHello: function (v) {
    //由于setTimeout异步,函数运行时所在的对象是setTimeout
    setTimeout(function () {
      console.log('this:', this) //this: Timeout {...}
      console.log('age:', this.age) //age: undefined
    }, 1000)
    return v * 2
  }
}
console.log('x:', Person.sayHello(2)) // x:4

箭头函数则不一样,它没有自己的this对象,内部的this就是定义时上层作用域中的this

var Person1 = {
  age: 18,
  sayHello: function (v) {
    //箭头函数上层作用域中的this,就是Person1对象
    setTimeout(() => {
      console.log('this:', this) // this: { age: 18, sayHello: [Function: sayHello] }
      console.log('age:', this.age) //age: 18
    }, 1000)
    return v * 2
  }
}
console.log('y:', Person1.sayHello(2)) // y:4

箭头函数不可以当作构造函数

function fun1(a, b) {
  console.log('new 函数,则函数是构造函数:', a + b)
}
const a1 = new fun1(1, 2)

const fun2 = (a, b) => {
  console.log('new 箭头函数,会报错:', a + b)
}
//const a2 = new fun2(1, 2) //会报错 

class类

ES6 的类,完全可以看作构造函数的另一种写法。
JS是用构造函数来充当”类“,TS类才是类似其他后端语言的类

class Point {
  // ...
}
console.log(typeof Point) // "function"
console.log(Point === Point.prototype.constructor) // true

下面代码中的三个方法,其实都是定义在Point.prototype上面。

class Point2 {
  constructor() {}
  toString() {}
  toValue() {}
}
// 等同于
Point2.prototype = {
  constructor() {},
  toString() {},
  toValue() {}
}

封装与继承
get和set

class Example {
  constructor(a, b) {
    console.log('构造函数')
    this.a = a // 实例化时调用 set 方法
    this.b = b
  }
  // get 函数名 和 属性同名 才会触发
  get a() {
    console.log('get-a')
    //return this.a  //这样也会不断循环,
    return this._a
  }
  get b() {
    console.log('get-b')
    return this.b
  }
  set a(v) {
    console.log('set-a:', v)
    //this.a = a  //自身递归调用,不断循环,最终导致 RangeError
    this._a = v
  }
  set b(v) {
    console.log('set-b:', v)
  }
}
let exam = new Example(1, 2) //构造函数  set-a: 1   set-b: 2
console.log(exam.a) //get-a  1


class Father1 {
  constructor() {}
  get a() {
    return this._a
  }
  set a(v) {
    this._a = v
  }
}
class Child1 extends Father1 {
  constructor() {
    super()
  }
}
let test1 = new Child1()
test1.a = 2
console.log(test1.a) // 2

模块

ES6 的模块化分为导出(export) @与导入(import)两个模块
模块中可以导入和导出各种类型的变量,如函数,对象,字符串,数字,布尔值,类等

每个模块都有自己的上下文,每一个模块内声明的变量都是局部变量,不会污染全局作用域
每一个模块只加载一次(是单例的), 若再去加载同目录下同文件,直接从内存中读取
导出的函数声明与类声明必须要有名称(export default 命令另外考虑)
export 命令可以出现在模块的任何位置,但必需处于模块顶层


Generator 函数

ES6新引入了Generator函数,可以通过yield关键字,把函数的执行流挂起,
为改变执行流程提供了可能,从而为异步编程提供解决方案。 基本用法
Generator 有两个区分于普通函数的部分:
一是在 function 后面,函数名之前有个 *
函数内部有 yield 表达式。
其中 * 用来表示函数为 Generator 函数,yield 用来定义函数内部的状态。

function* func() {
  console.log('one')
  yield '1'
  console.log('two')
  yield '2'
  console.log('three')
  return '3'
}
//调用 Generator 函数和调用普通函数一样,在函数名后面加上()即可,
//但是 Generator 函数不会像普通函数一样立即执行,而是返回一个指向内部状态对象的指针
const f = func() //不会立即执行,返回指针
console.log(f.next()) //one  { value: '1', done: false }
console.log(f.next()) //two  { value: '2', done: false }
console.log(f.next()) //three  { value: '3', done: true }
console.log(f.next()) // { value: undefined, done: true }
console.log(f.next()) // { value: undefined, done: true }
//如果执行第三步时,没有 return 语句的话,就直接返回 { value: undefined, done: true }
上一篇 下一篇

猜你喜欢

热点阅读