js小技巧

var textReg = /(.{10}).*/
var text = "控制文字的长度,其余用***表示"

text.replace(textReg, '$1***')


var mobileReg = /^(\d{3}).*(\d{4})$/  //可以匹配手机号和座机等
var mobile = "13590244124"

mobile.replace(mobileReg, '$1****$2')

()代表的是 分组,即小括号里面的小正则 捕获到的内容。($1--$9 是RegExp 自带的)

 

2.浮点数运算

function mul() {//乘法
      arguments = Array.from(arguments)//arguments不是真的数组,用不了concat方法
      var m = 0,
        arg = arguments.concat(),
        result = 1;
      arg.forEach((item, index) => {
        arg[index] = item.toString()// item = item.toString()改变不了原数组,如果是对象的就可以直接修改(js的基本类型 按值传递,对象类型按 共享传递)
        try {
              if (arg[index].indexOf('.') > -1)
                m += arg[index].split(".")[1].length;
        }catch (e) {
        }
      })
      arg.forEach(item => {
        result *= parseFloat(item.replace(".", ""))
      })
      return result / Math.pow(10, m);
}
function div () {//除
    arguments = Array.from(arguments)
    var m = 0,
        arg = arguments.concat(),
        pow = [],
        result = 1;
    arg.forEach((item, index) => {
        arg[index] = item.toString()
        if(index === 0){
            result *= parseFloat(arg[index].replace(".", ""))
        }
        try {
            if (arg[index].indexOf('.') > -1)
                   pow[index] = arg[index].split(".")[1].length;
        }catch (e) {
        }
    })
     arg.forEach( (item, index) => {
        if(index > 0)
            result /= parseFloat(item.replace(".", ""))
    })
    pow.forEach( (item, index) => {
        if(index === 0 && item){
            m -= item
        }else if(index > 0 && item){
            m += item
        }
    })
    return mul(result, Math.pow(10, m));
}
function add() {//加法
    arguments = Array.from(arguments)
    var m = 0,
        arg = arguments.concat(),
        pow = [],        
        result = 0;
    arg.forEach((item, index) => {
        arg[index] = item.toString()
        try {
            if (arg[index].indexOf('.') > -1)
                pow[index] = arg[index].split(".")[1].length;
        }catch (e) {
        }
    })
    m = Math.pow(10, Math.max(...pow))
    arg.forEach(item => {
        result += mul(item, m)
    })
    return result / m
}
function sub() {//减法
    arguments = Array.from(arguments)
    var m = 0,
        arg = arguments.concat(),
        pow = [],        
        result = 0;
    arg.forEach((item, index) => {
        arg[index] = item.toString()
        try {
            if (arg[index].indexOf('.') > -1)
                pow[index] = arg[index].split(".")[1].length;
        }catch (e) {
        }
    })
    m = Math.pow(10, Math.max(...pow))
    arg.forEach((item, index) => {
    if(index === 0){
        result += mul(item, m)
    }else{
        result -= mul(item, m)
    }
    })
    return result / m
}

 3.encodeURIComponent和decodeURIComponent

对于IE浏览器,query参数传中文字符串最好encodeURIComponent编码,不然IE9及以下浏览器可能出现乱码问题;

一个字符串,里面不包含‘%’(有调用decodeURIComponent会报错),可多次调用decodeURIComponent进行解码,内容一致;(%  编码成 %25)

4. null*1 === 0

//根据C语言的传统,null被设计成可以自动转为0
 typeof null === 'object'

//null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。

5 + undefined 为 NaN

//null表示"没有对象",即该处不应该有值。典型用法是:
//作为对象原型链的终点。

Object.getPrototypeOf(Object.prototype) === null

5. 左移运算符,右移运算符运用

2.3>>1  //1
-2.3>>1 //-1

//对于左运算,类似于先舍弃小数部分再乘于2的n次方向下取整
2.7<<2   可以理解成2*2^2

//对于右运算,类似于先舍弃小数部分再除于2的n次方向下取整
-12.7>>2   可以理解成-12/(2^2) 为-3
-15.9>>2   可以理解成-15/(2^2) 为-4

 6. 关于谷歌弹出默认选择密码框的问题

//当input的type为password的时候会自动弹出默认密码选择框

//方法一:初始化的时候设置type为text,然后监听onChange事件
//当value不为空时置type为password
// 弊端,浏览器自动填充密码的时候会明文

//方法二:设置为readOnly,当获得焦点的时候,延迟设置e.target.readOnly=false
// 当失去焦点的时候,重新设置e.target.readOnly=true

7. 选用浏览器的密码填充后,会出现默认的背景色

&:-webkit-autofill {
    -webkit-box-shadow: 0 0 0 1000px #272789 inset;//背景色
    -webkit-text-fill-color: #FFF;//填充文字颜色
    caret-color: #FFF;//鼠标颜色
}

 8. 避免浏览器缓存get请求

request.interceptors.request.use(function (config) {
  // let token = window.localStorage.getItem('token') || ''
  // if(token){
  //   config.headers['Authorization'] = 'bearer ' + token
  // }

  if(config.method.toLowerCase() === 'get'){
    if (!config['params']) { //如果这个请求本身不带参数
      Object.assign(config, {   //给options这个对象添加一个params的参数,属性为_,值为时间戳
        params: {
          _: new Date().getTime()
        }
      })
    } else {
      Object.assign(config.params, { //如果get请求本身带有参数,给options.params 再添加一个key值_,值为时间戳
        _: new Date().getTime()
      })
    }
  }

  return config;
}, function (error) {
  // Do something with request error
  return Promise.reject(error);
});

 9. 判断是否为IE

isIE = () => {
    // return window.navigator.userAgent.indexOf('MSIE') > -1; //ie 11 失效
    if (!!window.ActiveXObject || "ActiveXObject" in window){
      return true;
    }else {
      return false;
    }
  }

10 window.open(url) 和window.open(url, '__blank') 的区别

区别在于从主页面window.open(url) 永远都是新开个标签页,window.open(url, '__blank')会检测如果已经从主页面新开标签页,会复用

原因:

window.open(strUrl, strWindowName, [strWindowFeatures]);

//strWindowName 新窗口的名称。该字符串可以用来作为超链接 <a> 或表单 <form> 元素的目标属性值。字符串中不能含有空白字符。注意:strWindowName 并不是新窗口的标题。

这里之所以复用新标签页,是因为'__blank',只是单独的一个名称,而非'_blank'

如果已经存在以 strWindowName 为名称的窗口,则不再打开一个新窗口,而是把 strUrl 加载到这个窗口中。在这种情况下,方法的返回值是这个已经打开的窗口,并忽略参数 strWindowFeatures 。如果要在每次调用 window.open()时都打开一个新窗口,则要把参数 strWindowName 设置为 _blank。如果要在本标签页打开,则设置为_self

 11. 深度合并对象以及深度合并对象的某些属性

function deepExtend(obj1, obj2) {
  if (Object.prototype.toString.call(obj1) === '[object Object]' && Object.prototype.toString.call(obj2) === '[object Object]') {
    for (let prop2 in obj2) {//obj1无值,都有取obj2
      if (!obj1[prop2]) {
        obj1[prop2] = obj2[prop2];
      } else {//递归赋值
        obj1[prop2] = deepExtend(obj1[prop2], obj2[prop2]);
      }
    }
  } else if (Object.prototype.toString.call(obj1) === '[object Array]' && Object.prototype.toString.call(obj2) === '[object Array]') {
    // 两个都是数组,简单进行替换
    // obj1 = obj2;
    for (let prop2 in obj2) {//obj1无值,都有取obj2
      if (!obj1[prop2]) {
        obj1[prop2] = obj2[prop2];
      } else {//递归赋值
        obj1[prop2] = deepExtend(obj1[prop2], obj2[prop2]);
      }
    }
  } else {//其他情况,取obj2的值
    obj1 = obj2;
  }
  return obj1;

}

function deepExtendSomeAttrs(obj1, obj2, attrs, prop) {
  if (Object.prototype.toString.call(obj1) === '[object Object]' && Object.prototype.toString.call(obj2) === '[object Object]') {
    for (let prop2 in obj2) {//obj1无值,都有取obj2
      if (!obj1[prop2]) {
        if(attrs && attrs.includes(prop2)){
          obj1[prop2] = obj2[prop2];
        }
        if(!attrs){
          obj1[prop2] = obj2[prop2];
        }
      } else {//递归赋值
        obj1[prop2] = deepExtendSomeAttrs(obj1[prop2], obj2[prop2], attrs, prop2);
      }
    }
  } else if (Object.prototype.toString.call(obj1) === '[object Array]' && Object.prototype.toString.call(obj2) === '[object Array]') {
      if(attrs && attrs.includes(prop)){
        if(obj1.length < obj2.length){
          obj1 = obj2;
        }
      }
      if(!attrs){
        for (let prop2 in obj2) {//obj1无值,都有取obj2
          if (!obj1[prop2]) {
              if(attrs && attrs.includes(prop2)){
              obj1[prop2] = obj2[prop2];
              }
              if(!attrs){
              obj1[prop2] = obj2[prop2];
              }
          } else {//递归赋值
              obj1[prop2] = deepExtendSomeAttrs(obj1[prop2], obj2[prop2], attrs, prop2);
          }
        }
      }

  } else {//其他情况,取obj2的值
    if(attrs && attrs.includes(prop)){
      obj1 = obj2;
    }
    if(!attrs){
      obj1 = obj2;
    }
  }
  return obj1;

}

 

posted @ 2018-06-20 18:42  潮哥  阅读(184)  评论(0编辑  收藏  举报