BUG总结

最新更新时间:2019年05月21日17:51:48

《猛戳-查看个人博客地图-总有你意想不到的惊喜》

本文内容:平常bug汇总javascript

概述

在个人工做经历中,做为一名基层开发工程师,开发业务过程当中,会遇到大大小大的问题,这里主要记录耗时较长的问题前端

数组filter错误的用法

问题时间:2019年05月17日
问题描述:用户管理系统,用户类型分为,一级用户,二级用户,三级用户,每一个级别用户看到的左侧树目录不同,管理权限越高,看到的目录越多,所以须要过滤处理。可是以下方案一,出现的错误是权限越低的用户登陆过,高级别权限的用户看到的是较少的目录。缘由:引用类型问题,返回的结果没有切断和原数组的引用vue

//不该该对原始数组userPermissionArr进行操做
  function filterArr(userPermissionArr, roles) {
    //这条语句没有问题,filter方法不对原始数组进行操做,而且返回新数组
    const res = userPermissionArr.filter(item => {
      if (allow(roles, item)) {
        if (item.children && item.children.length) {
          //下面这句递归语句有问题,虽然filter方法返回新数组,不对原数组进行操做,可是route.children仍是原始数组的引用,所以原数据被改变了,致使后续逻辑出错
          item.children = filterArr(item.children, roles)
        }
        return true
      }
      return false
    })
    return res
  }
//以下双层forEach方法,彻底切断了引用
  function filterArr(userPermissionArr, roles) {
    const res = []
    userPermissionArr.forEach((item, idx1) => {
      if (allow(roles, item)) {
        if (item.children && item.children.length) {
          res[res.length] = { ...item }
          res[res.length - 1].children = []
          item.children.forEach((child, idx2) => {
            if (allow(roles, child)) {
              res[res.length - 1].children.push({ ...child })
            }
          })
        } else {
          res.push({ ...item })
        }
      }
    })
    return res
  }
  • 注意:api好用,可是弊端须要掌握

react异步dom问题

问题时间:2019年05月21日
问题描述:react移动端的项目,图片预览功能,使用react-cropper组件,点击图片打开预览,点击预览区域任意地方能够关闭预览,可是第三方组件在iOS设备上不支持关闭,猜想react-cropper组件dragMode='move’的属性,阻止了click事件,综合考虑后,在预览界面右上角加关闭icon,解决了iOS不兼容的问题。java

//场景一
componentDidMount() {
    let _this = this;
    let dom = document.getElementsByClassName('cropper-drag-box')
    console.log(dom);
    //控制台打印以下,看上去是一个空数组,即没有拿到'cropper-drag-box'元素
    //HTMLCollection []
    
    //展开以后,以下,确实存在元素,能够得出react页面在异步渲染,'cropper-drag-box'元素是异步生成的,首次打印的时候尚未生成真实dom
    //HTMLCollection []
		//0: div.cropper-drag-box.cropper-move
		//length: 1
		//__proto__: HTMLCollection
}
//场景二:以下报错,也是异步渲染缘由
componentDidMount() {
	let _this = this;
	let dom = document.getElementsByClassName('cropper-drag-box')[0]
	console.log(dom);//undefined
	dom.addEventListener('click',function(){},false)
	//Uncaught TypeError: Cannot read property 'addEventListener' of undefined
}
//上面两种错误的解决方案
componentDidMount() {
	let dom = null
	setTimeout(function(){
		dom = document.getElementsByClassName('cropper-drag-box')[0]
		console.log(dom);
		dom.addEventListener('click',function(){},false)
	},1000)
}
  • 扩展:vue中处理异步dom的方案,this.$nextTick(function(){console.log(1)})

上传文件剔除非法格式文件算法出错

问题时间:2019年05月25日
问题描述:本地上传文件,须要校验文件格式,以读取到的文件名来剔除非法文件node

//方案一:当文件名中包含格式名的时候会出错
let isFormat = false
const arrList = ['pdf', 'ppt', 'pptx', 'doc', 'docx']
for (let i = 0; i < arrList.length; i++) {
	//若是文件名包含 pdf 则判断失效:好比'这不是一个pdf文件.rmvb'
	if (file.name.toLowerCase().indexOf(arrList[i]) !== -1) {
		isFormat = true
	}
}
//方案二:取文件名末尾,不会出错
let isFormat = false
const arrList = ['pdf', 'ppt', 'pptx', 'doc', 'docx']
	for (let i = 0; i < arrList.length; i++) {
	if (file.name.split('.').pop() === arrList[i]) {
		isFormat = true
	}
}

react项目在移动端iOS 9 如下打开白屏&&空白页面

问题时间:2019年06月13日
问题描述:用目前市面上的全部react脚手架构建项目,都会出如今iOS 9的手机上没法打开页面,出现白屏,包括官方的create-react-app脚手架。这个问题耗时半个月,最终定位到核心问题是,babel 7没有配置好。react

//.babelrc文件 失败的配置
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-proposal-function-bind",
    "@babel/plugin-proposal-class-properties"
  ]
}
//.babelrc文件 成功的配置
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": ["safari >= 8"]
        }
      }
    ],
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-proposal-function-bind",
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-transform-runtime"
  ]
}

Object.assign is not a function

移动端项目开发过程当中,低版本手机系统(iOS 9 如下)的浏览器不兼容Object.assign语法,所以须要作兼容处理webpack

//场景一
let a = {a:2,b:2};
let b = {c:3,d:3,a:5};

let c = Object.assign(a,b);//将b对象合并到a对象上,并返回a对象

console.log(c);//{ a: 5, b: 2, c: 3, d: 3 }
console.log(c === b);//false
console.log(c === a);//true
console.log(a === b);//false

console.log(c == b);//false
console.log(c == a);//true
console.log(a == b);//false
//场景二
let a = {a:2,b:2};
let b = {c:3,d:3,a:5};

let c = Object.assign({},a,b);//将b对象合并到a对象上,再将a对象合并到新对象上,返回新对象

console.log(c);//{ a: 5, b: 2, c: 3, d: 3 }
console.log(c == b);//false
console.log(c == a);//false
//场景三 Object.assign is not a function 兼容处理
//全局定义 Object.assign
if(typeof Object.assign != 'function'){
    Object.assign = function(target) {//target 最终输出的结果
        'use strict';
        if (target == null) {//undefined == null true null == null true
            throw new TypeError('Cannot convert undefined or null to object');
        }
        console.log(target == Object(target))
        target = Object(target);//target == Object(target) true
        for(var i = 1;i<arguments.length;i++) {
            var source = arguments[i];
            if (source != null) {
                for (var key in source) {
                    if (Object.prototype.hasOwnProperty.call(source, key)) {
                        target[key] = source[key];
                    }
                }
            }
        }
        return target;
    };
}

控制台报错“SyntaxError: Unexpected end of input”

前端代码本地实时编译打包,webpack启动本地服务没有问题;经过命令scp -r /Users/wanshaobo/project/xdf-middle-school-webview/old/ root@172.22.31.45:/root/project/old将包发布到服务器,此时服务器报错磁盘已满,看上去包已经发布成功,可是经过域名访问这个网站报错SyntaxError: Unexpected end of input。通过排查,重启nginx修复了这个报错。nginx

通过排查,致使这个报错不是nginx的问题,是由于本地从新安装了node包,致使语法格式变换;es6

//修复前
//a.js
export const options = []
export const subjectInfo = arr[2]
export const requestTips = {
  timeout: '哎呀,加载超时了,请刷新重试~'
}
//在b.js中使用a.js
import { requestTips } from '../../common/dic'

//修复后
//a.js
const options = []
const subjectInfo = arr[2]
const requestTips = {
  timeout: '哎呀,加载超时了,请刷新重试~'
}
module.exports =  {
  options,
  subjectInfo,
  requestTips
}

Module 的语法 - ECMAScript 6入门web

参考资料

感谢阅读,欢迎评论^-^

打赏我吧^-^