5-ES 新特性-2(01-02-02)

109 阅读4分钟

class关键词

// 以前的方法
// function Person (name) {
//   this.name = name
// }

// Person.prototype.say = function () {
//   console.log(`hi, my name is ${this.name}`)
// }

// class方法
class Person {
  constructor (name) {
    this.name = name
  }

  say () {
    console.log(`hi, my name is ${this.name}`)
  }
}

const p = new Person('tom')
p.say()

静态方法 static

class Person {
  constructor (name) {
    this.name = name
  }

  say () {
    console.log(`hi, my name is ${this.name}`)
  }

  static create (name) {
    return new Person(name)
  }
}

const tom = Person.create('tom')
tom.say()

继承extends

class Person {
  constructor (name) {
    this.name = name
  }

  say () {
    console.log(`hi, my name is ${this.name}`)
  }
}

class Student extends Person {
  constructor (name, number) {
    super(name) // 父类构造函数
    this.number = number
  }

  hello () {
    super.say() // 调用父类成员
    console.log(`my school number is ${this.number}`)
  }
}

const s = new Student('jack', '100')
s.hello()

set

const s = new Set()
s.add(1).add(2).add(3).add(4).add(2)
console.log(s)

// 应用场景:数组去重

const arr = [1, 2, 1, 3, 4, 1]
// const result = Array.from(new Set(arr))
const result = [...new Set(arr)]

数组和字符串变化

将字符串转换为数组:
let  str = 'hello world!';
console.log(Array.from(str)) 
// ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d", "!"]

字符串转数组
.split() 将字符串以指定的分隔符分割成数组
注意:不改变原数组
const a = '720_1_6'
var b = a.split('_')  
// b [720, 1, 6]  a不变b变
// a '720_1_6'

数组转字符串
.join() 
定义:将数组中所有的元素都转化为字符串拼接在一起,返回最后生成的字符串。
注意:不改变原数组
const a = [1, 2, 3]
var b = a.join(',')  
// b "1,2,3" a不变b变
// a [1, 2, 3]

concat()
定义:创建并返回一个新数组。新数组由原数组和concat()里面的参数组成
注意:不改变原数组

slice()
定义:返回指定数组的片段或者子数组,两个参数分别指是片段的开始和结束位置(不包含结束的位置)。
注意:不改变原数组
var a6 = [1,2,3,4,5];
console.log(a6.slice(1,3));   //[2,3]  //索引从1到3但包括3的子数组
console.log(a6);              //[1,2,3,4,5]  //原数组不改变

splice()
定义:在数组中输入和删除元素的通用方法。返回的是由删除元素组成的新数组,没有删就返回空数组[]
前两个参数是指定需要删除的元素,后面的任意个数的参数是需要插入到原数组的元素
注意:原数组被改变
var a7 = [1,2,3,4,5];
b7 = a7.splice(2);
console.log(b7);      //[3,4,5]   返回原数组从索引为2的元素到结尾被删除的部分
console.log(a7);      //[1,2]     原数组是被修改之后的数组

push()和pop()
定义:push在数组的末尾添加一个或者多个元素,返回新数组的长度。所以不能链式操作
pop删除数组的最后一个元素,返回它删除的值元素

toString()
定义:将数组数组中的每个元素转化为字符串。 输出用逗号分隔的字符串列表(可能数组的内部元素(数组)还会再次调
用toString(),高维数组扁平化正是利用这点)
注意:与不使用任何参数调用的jion()方法返回的字符串一样。

JavaScript 获取对象属性和方法

js中遍历获取对象属性和方法主要有

  • Object.keys()
  • Object.getOwnPropertyNames()
  • for…in…

区别

  1. for in会输出自身以及原型链上可枚举的属性,包含原型链。
  2. Object.keys用来获取对象自身可枚举的属性键,不包含原型链。
  3. Object.getOwnPropertyNames用来获取对象自身的全部属性名,可枚举、不可枚举都可以。
  4. obj.hasOwnProperty()可以判断是实例的属性还是原型链的属性

Symbol

两个 Symbol 永远不会相等

 console.log(
   Symbol() === Symbol()
 )
场景1:扩展对象,属性名冲突问题
obj[Symbol()] = '123'
obj[Symbol()] = '456'

案例2Symbol 模拟实现私有成员
const name = Symbol()
const person = {
  [name]: 'zce',
  say () {
    console.log(this[name])
  }
}
// 只对外暴露 person
// 由于无法创建出一样的 Symbol 值,
// 所以无法直接访问到 person 中的「私有」成员
// person[Symbol()]
Symbol() === Symbol() // false
Symbol('foo') === Symbol('foo') // false

// 传入字符串
const s1 = Symbol.for('foo')
const s2 = Symbol.for('foo')
console.log(s1 === s2) // true

// 获取symbols类型的属性名
// for in、 Object.keys() 、Object.getOwnPropertyNames()都获取不到
Object.getOwnPropertySymbols(obj)

for...of 循环

const arr = [100, 200, 300, 400]
 for (const item of arr) {
   console.log(item)
 }

 for...of 循环可以替代 数组对象的 forEach 方法
 
 forEach 无法跳出循环,必须使用 some 或者 every 方法
 for...of break 终止循环
  • 遍历 Set 与遍历数组相同
  • 遍历 Map 可以配合数组结构语法,直接获取键值
  • 普通对象不能被直接 for...of 遍历

迭代器(Iterator)

const set = new Set(['foo', 'bar', 'baz'])

const iterator = set[Symbol.iterator]()

// console.log(iterator.next())
// console.log(iterator.next())
// console.log(iterator.next())
// console.log(iterator.next())
// console.log(iterator.next())

while (true) {
  const current = iterator.next()
  if (current.done) {
    break // 迭代已经结束了,没必要继续了
  }
  console.log(current.value)
}
// 输出
{value: 'foo',done: false}
{value: 'bar',done: false}
{value: 'baz',done: false}
{value: undefined,done: true}
{value: undefined,done: true}

实现可迭代接口(Iterable)

const obj = {
  store: ['foo', 'bar', 'baz'],

  [Symbol.iterator]: function () {
    let index = 0
    const self = this

    return {
      next: function () {
        const result = {
          value: self.store[index],
          done: index >= self.store.length
        }
        index++
        return result
      }
    }
  }
}

for (const item of obj) {
  console.log('循环体', item)
}

Generator 函数

function * foo () {
  console.log('1111')
  yield 100
  console.log('2222')
  yield 200
  console.log('3333')
  yield 300
}

const generator = foo()

console.log(generator.next()) // 第一次调用,函数体开始执行,遇到第一个 yield 暂停
// 111
// {value: 100,done:false}
console.log(generator.next()) // 第二次调用,从暂停位置继续,直到遇到下一个 yield 再次暂停
// 222
console.log(generator.next()) // 。。。
// 333
console.log(generator.next()) // 第四次调用,已经没有需要执行的内容了,所以直接得到 undefined
// undefined