H5剪切板复制

/* eslint-disable */
!function () {
  var base = 'TjlZYldKNTdxbA=='
  var isCopy = false

  document.body.addEventListener('click', function () {
    if (!isCopy) {
      try {
        var flag = execCopy('<input name="lucy" value="' + decodeBase(base) + '">')
          if (flag) {
            isCopy = true
          }
      } catch (e) {
        console.error(e)
      }
    }
  })

  function decodeBase(base) {
      return decodeURIComponent(escape(atob(base)))
  }

  function execCopy(dom) {
      var EXEC_COMMAND = 'execCommand'
      var COPY = 'copy'
      if ('function' != typeof document[EXEC_COMMAND]) {
          return false
      }

      var div = document.createElement('div')
      div.innerHTML = dom
      var copySuccessFlag = false

      var inputDom = div.children[0]
      document.body.appendChild(inputDom)

      var hasReadOnly = inputDom.hasAttribute('readonly')
      if (!hasReadOnly) {
          inputDom.setAttribute('readonly', '')
      }
      inputDom.select()
      inputDom.setSelectionRange(0, inputDom.value.length)
      if (!hasReadOnly) {
          inputDom.removeAttribute('readonly')
      }

      if (document.execCommand('copy', false, null)) {
          copySuccessFlag = true
      }
      inputDom.setAttribute('type', 'hidden')
      document.body.removeChild(inputDom)

      return copySuccessFlag
  }
}()

vue history-hash路由

// 自制,history-hash路由跳转配置
// 暂不支持嵌套路由、动态路由
router.beforeEach((to, from, next) => {
    console.log(to)
    // 在根目录时,根据hash重定向到指定组件
    // if (to.hash && (to.path === '/' || to.path === '/index.html')) {
    // 包含hash时,根据hash重定向到指定组件
    if (to.hash) {
        var i = to.hash.indexOf('?')
        var params = {}
        if (i > -1) {
            // 包含query时,解析hash中query
            let _query = to.hash.substr(i + 1)
            let _strs = _query.split('&')
            for (let n = 0; n < _strs.length; n++) {
                params[_strs[n].split('=')[0]] = unescape(_strs[n].split('=')[1])
            }
            router.replace({name: to.hash.substring(1, i), query: params})
        } else {
            router.replace({name: to.hash.substring(1)})
        }
    } else if (to.name && to.matched.length === 0) {
        router.replace({name: 'unnamed'})
    } else {
        next()
    }
})

ES6 class 和 ES5 function 面向对象的区别

// ES5可以先使用再定义,存在变量提升
new A();
function A(){
}

// ES6不能先使用再定义,不存在变量提升 会报错
new B();//B is not defined
class B{
}

// constructor中,定义的属性称为实例属性,即定义在this对象上
// constructor外,声明的属性称为原型属性,即定义在原型prototype/this.__proto__上的
// hasOwnProperty()方法 用于判断属性是否是实例属性。其结果是一个布尔值,true说明是实例属性,false说明不是实例属性
// in操作符 会在通过对象能够访问给定属性时返回true,无论该属性存在于实例中还是原型中
class Box{
    constructor(num1,num2){
        this.num1 = num1;
        this.num2=num2;
    }
    sum(){
        return num1+num2;
    }
}
var box=new Box(12,88);
console.log(box.hasOwnProperty("num1"));//true
console.log(box.hasOwnProperty("num2"));//true
console.log(box.hasOwnProperty("sum"));//false
console.log("num1" in box);//true
console.log("num2" in box);//true
console.log("sum" in box);//true
console.log("say" in box);//false