美文网首页
JavaScript 使用问题

JavaScript 使用问题

作者: 想聽丿伱說衹愛我 | 来源:发表于2021-06-10 17:15 被阅读0次
    1. 判断对象为空
    JSON.stringify(object) === '{}'
    Object.keys(object).length === 0
    
    1. 在回调函数中this为undefined
      setTimeout(function() { this }, 1000)的回调函数中this为undefined。
    • 可使用箭头函数作为回调函数
      setTimeout(() => { this }, 1000)
    • 可让this先赋值给一个变量
    var scope = this
    setTimeout(function() { scope }, 1000)
    
    1. 判断对象的值时一定要先做非空判断
      否则运行会在此处停止,也不报错。
    let a = {a: 1, b: 3}
    if (a && a.c) {
        console.log("a.c存在")
    } else {
        console.log("a.c不存在")
    }
    

    此时会走else分支。
    若使用下面代码

    let a = {a: 1, b: 3}
    if (a && a.c.d) {
        console.log("a.c.d存在")
    } else {
        console.log("a.c.d不存在")
    }
    

    此时当代码运行到a.c.d处就会停止,不再执行后面代码。
    正确写法为

    let a = {a: 1, b: 3}
    if (a && a.c && a.c.d) {
        console.log("a.c.d存在")
    } else {
        console.log("a.c.d不存在")
    }
    

    也可以写成(a && a.c && a.c.d) ? a.c.d : ""
    也可以使用链运算符(a?.c?.d) ? a.c.d : ""

    1. 导入excel转换为对象
    importXLSX: function(callback) {
            // 创建input file
            let file = document.createElement('input')
            file.setAttribute('id','filefilefilefilefilefilefile');
            file.setAttribute('type','file');
            file.setAttribute('accept','.xlsx');
            file.setAttribute("style",'visibility:hidden');
            document.body.appendChild(file);
            // 监听选择事件
            file.addEventListener('change', val => {
                let xlsx = val.target.files[0]//取选择的第一个文件
                if (xlsx) {
                    //将xlsx转换为对象
                    let reader = new FileReader()
                    reader.onload = function(e) {
                        let cfb = XLSX.read(e.target.result, {type: 'binary'})
                        let sheetName = cfb.SheetNames[0]//每个excel有多个工作表 这里取第一个
                        let oJS = XLSX.utils.sheet_to_json(cfb.Sheets[sheetName])
                        callback(oJS)
                    };
                    reader.readAsBinaryString(xlsx)
                }
            })
            //触发点击事件弹出文件选择
            file.click();
        },
    

    使用上面方法获取的对象,你会发现时间会变成一个数字,可使用下面方法来转换成正常时间。

    formatExcelDate(num, format="yyyy-MM-dd HH:mm:ss") {
            if (isNaN(Number(num))) {
                return num
            }       
            const time = new Date((num - 1) * 24 * 3600000 + 1)
            time.setYear(time.getFullYear() - 70)
            time.setHours(time.getHours() - 8)
            const year = time.getFullYear() + ''
            const month = time.getMonth() + 1 + ''
            const day = time.getDate() + ''
            const hours = time.getHours() + ''
            const hours1 = time.getHours()%12 + ''
            const minutes = time.getMinutes() + ''
            const seconds = time.getSeconds() + ''
            const option = {
                "Y+": year,
                "y+": year,
                "M+": month,
                "d+": day,
                "H+": hours,
                "h+": hours1,
                "m+": minutes,
                "s+": seconds,
                // 有其他格式化字符需求可以继续添加,必须转化成字符串
            }
            for (let k in option) {
                let ret = new RegExp("(" + k + ")").exec(format);
                if (ret) {
                    if (ret[1].length > option[k].length) {
                        //如果format每项的长度大于日期对应的数值 即yyyyy和2021,此时要上2021前补0 
                        format = format.replace(ret[1], option[k].padStart(ret[1].length, "0"))
                    } else {
                        //若小于 即yy与2021,此时只取后面的21
                        format = format.replace(ret[1], option[k].slice(option[k].length - ret[1].length))
                    }
                }
            }
            return format
        }, 
    
    1. 将对象导出为excel
    exportXLSX: function(array, titles, fileName = "list.xlsx") {
            if (!array || array.length == 0) return
            let datas = []
            // 将 {a: "测试", b: "张三"} 变成 {"标题": "测试", "姓名": "张三"}
            for (let item of array) {
                let dict = {}
                for (let t in titles) {
                    if (t.indexOf("$") != -1) {
                        //t中有$ 向最里层取值
                        let itemValue = item
                        let keys = t.split("$")
                        for (let s of keys) {
                            itemValue = itemValue[s]
                        }
                        let titleValue = titles[t]
                        dict[titleValue] = itemValue
                    } else {
                        //t中没有$ 根据titleValue的类型取值
                        let last = array.indexOf(item) == (array.length - 1)//是否为最后一项
                        let titleValue = titles[t]
                        let itemValue = item[t]
                        while (titleValue) {
                            if (typeof(titleValue) == "string") {
                                //titleValue为字符串时 直接赋值
                                dict[titleValue] = itemValue;
                                if (last) {
                                    //当最后一个元素时 将titles中的value变成中文字符串 以供json_to_sheet使用 
                                    //即 {c: {d: "年龄" }}, 变为 {c: "年龄"}
                                    //若在第一个元素时修改 会影响后续元素的判断 所以在最后一个元素时修改
                                    titles[t] = titleValue
                                }
                                break
                            } else if (typeof(titleValue) == "object") {
                                //支持嵌套判断 此处只判断是否为对象 请不要传正则、数组等 它们也是对象
                                let nextTitleKey = Object.keys(titleValue)[0]
                                let nextTitleValue = Object.values(titleValue)[0]
                                itemValue = itemValue[nextTitleKey]
                                titleValue = nextTitleValue
                            } else {
                                break
                            }
                        }
                    }
                }
                datas.push(dict)
            }
            // 创建一个工作薄对象
            let wb = XLSX.utils.book_new()
            // 将数据转换为工作表 表头为titles中的value
            let ws = XLSX.utils.json_to_sheet(datas, { header: Object.values(titles) })
            // 工作薄中添加一个表sheet 表的内容为ws
            let sheetName = "sheet"
            wb.SheetNames.push(sheetName)
            wb.Sheets[sheetName] = ws
            //写入的样式
            let wopts = { 
                bookType: 'xlsx', bookSST: false, type: 'binary', cellStyles: true, showGridLines: false ,
            } 
            //创建二进制对象写入转换好的字节流
            let wbout = XLSX.write(wb, wopts)
            let blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' })
            // 创建对象超链接
            var href = URL.createObjectURL(blob); 
            // 创建a标签 模拟点击事件下载文件
            let a = document.createElement('a')
            a.setAttribute('id','downloaddownloaddownloaddownload')
            a.setAttribute('href', href)
            a.setAttribute('download', fileName)
            a.setAttribute("style", 'visibility:hidden')
            document.body.appendChild(a);
            a.click()
            setTimeout(function() {
                //释放字节流
                URL.revokeObjectURL(blob);
            }, 100);
        }
    
    // 字符串转字符流
    function s2ab(s) { 
        var buf = new ArrayBuffer(s.length);
        var view = new Uint8Array(buf);
        for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
        return buf;
    }
    

    titles支持如下

    titles: {
            a: "标题",
            b: "姓名",
            c: {
                d: "年龄"
            },
            e: {
                f: {
                    g: "地址"
                }
            },
            "h$i$j": "特殊1",
            "h$i$k": "特殊2",
            l: {
                m: "特殊3",//不支持导出下面的n 只会导出m
                n: "特殊4"//不支持 请使用 "l$n": "特殊4"
            }
        }
    
    1. 在字符串中插入变量
    let a = aaa
    let b = "111" + a + "222"
    let c = `111${a}222`
    

    必须使用数字1左边的`,${}才有效。

    1. 三相运算符
      通常会使用let a = b ? b : "",当b为不为空时,a赋值为b,否则a赋值为""。
      可写成let a = b || "",也能实现对应功能,这个写法会在 b 为false 0 null undefined时执行;
      可写成let a = b ?? "", 与 || 功能相同,但只有b为null undefined时才会执行。

    相关文章

      网友评论

          本文标题:JavaScript 使用问题

          本文链接:https://www.haomeiwen.com/subject/qdeosltx.html