class的语法

类的新申明方式
class Point {
  // 静态属性,定义在类的最顶层
  bar = 'hello';
  baz = 'world';
  // 构造器,类似python的__init__
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

const p = new Point('zaza', 'yaya')
console.log(p.toString())
取值函数(getter)和存值函数(setter)
class MyClass {
  constructor() {
    // ...
  }
  get prop() {
    return 'getter';
  }
  set prop(value) {
    console.log('setter: '+value);
  }
}

let inst = new MyClass();

inst.prop = 123;
// setter: 123

inst.prop
// 'getter'
静态方法
class Foo {
  static classMethod() {
    return 'hello';
  }
}

Foo.classMethod() // 'hello'

var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function

Class的继承

class Point {
}

class ColorPoint extends Point {
}

class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
  }

  toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
  }
}

Promise 对象

// then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

// 链式调用(此方法为目前最优雅的调用方法)
new Promise((resolve, reject) => {
  // 建议异步只处理一次网络请求,并返回相关数据传递给then继续做另外一次异步处理
  // 模拟异步操作
  setTimeout(()=>{
    // 第一次调用必须使用resolve或者reject调用,return不行
    resolve('OK')
  },5000)
}).then(data => {
  console.log(data);
  // throw 和 Promise.reject来抛出异常数据,由最后的catch捕获,异常具有传递性
  // throw data + '异常'
  // return Promise.reject(data + '异常')
  // 正常数据返回
  // return Promise.resolve(data + '111')
  return data + '111' // 是这个方法的简写: return Promise.resolve(data + '111')
}).then(data => {
  console.log(data);
  return data + '222'
}).then(data => {
  console.log(data);
  return Promise.reject(data + '异常')
  // return data + '333'
}).then(data => {
  console.log(data);
}).catch(data => {
  console.log('异常捕获: ' + data);
})

axios链式请求

const axios = require('axios')

// 全局配置文件
axios.defaults.baseURL = 'https://httpbin.org';
axios.defaults.timeout = 100000;

console.log('第一次异步请求数据:/json');
axios.get('/json').then(response =>{
  const author = response.data.slideshow.author
  console.log('第一次异步请求返回的数据:' + author);
  const authorBase64 = Buffer.from(author).toString('base64');
  console.log('第二次异步请求数据:' + author+': '+ authorBase64 );
  // 通过异步获取到的数据请求其它数据
  return axios.get("/base64/" + authorBase64)
}).then(response => {
  console.log('第二次异步请求返回的数据:' + response.data);
  console.log('第三次异步请求数据:/delay/1');
  return axios.get("/delay/1")
}).then(response => {
  console.log('第三次异步请求返回的数据:' + response.data.url);
}).catch(err => {
  console.log('异常数据:' + err);
})

将数组push到另外一个数组里面

let totalNums = []
const num1 = [1, 2, 3]
const num2 = [4, 5, 6]
// ...为可变参数
totalNums.push(...num1)
totalNums.push(...num2)
console.log(totalNums);

$ node.exe array_push_array.js
[ 1, 2, 3, 4, 5, 6 ]

防抖和节流

// https://www.cnblogs.com/cc-freiheit/p/10827372.html
// 合成版
/**
   * @desc 函数防抖
   * @param func 目标函数
   * @param wait 延迟执行毫秒数
   * @param immediate true - 立即执行, false - 延迟执行
   */
function debounce(func, wait, immediate) {
    let timer;
    return function() {
      let context = this,
          args = arguments;
           
      if (timer) clearTimeout(timer);
      if (immediate) {
        let callNow = !timer;
        timer = setTimeout(() => {
          timer = null;
        }, wait);
        if (callNow) func.apply(context, args);
      } else {
        timer  = setTimeout(() => {
          func.apply
        }, wait)
      }
    }
}

/**
 * @desc 函数节流
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param type 1 表时间戳版,2 表定时器版
 */
function throttle(func, wait, type) {
  if (type === 1) {
    let previous = 0;
  } else if (type === 2) {
    let timeout;
  }
  return function() {
    let context = this;
    let args = arguments;
    if (type === 1) {
        let now = Date.now();
 
        if (now - previous > wait) {
          func.apply(context, args);
          previous = now;
        }
    } else if (type === 2) {
      if (!timeout) {
        timeout = setTimeout(() => {
          timeout = null;
          func.apply(context, args)
        }, wait)
      }
    }
  }
}

// vue 讲师版本
function debounce(func, delay) {
  let timer = null
  if (timer) clearTimeout(timer)
  timer = setTimeout(()=>{
    // 函数.apply(对象,函数需要的参数列表是一个数组)
    // fun.apply(thisArg,[argsArray])
    func.apply(this, args)
  },delay)
}

事件循环

console.log('aaa');
setTimeout(()=>{
  console.log('bbb');
})
console.log('ccc');

# 尽管setTimeout没有写时间但是打印顺序任然是aaa > ccc > bbb
# 因为异步操作永远是事件循环的最后才执行的