开发中经常使用的JS知识点集锦

索引javascript

一、对象的深拷贝(一级属性拷贝和多级属性嵌套拷贝)java

//深拷贝函数(知足属性多级嵌套)
function deepCloneObj(sourceObj){
    var obj = (sourceObj instanceof Array) ? [] : {};
    
    for (var key in sourceObj){
        var tmp = sourceObj[key];
        
        //处理重复引用,防止死循环
        if (tmp === sourceObj){
            continue; 
        }

        if (typeof tmp === 'object'){
            obj[key] = arguments.callee(tmp); //属性为对象,递归深度复制
        }
        else{
            obj[key] = tmp;
        }
    }
    return obj;
}

//一、测试对象的深拷贝
var obj = {info:{name:'大锤'}, sign: 'xxx'};
var obj2 = Object.assign({}, obj);  //一级属性深拷贝 (es6的Object.assign函数特性)
var obj3 = {...obj};            //一级属性深拷贝 (es6扩展运算符)
var obj4 =  deepCloneObj(obj);  //递归深拷贝全部层级属性
var obj5 = JSON.parse(JSON.stringify(obj)); //深拷贝全部层级属性

console.log('obj: ', JSON.stringify(obj));
console.log('obj2: ', JSON.stringify(obj2));
console.log('obj3: ', JSON.stringify(obj3));
console.log('obj4: ', JSON.stringify(obj4));
console.log('obj5: ', JSON.stringify(obj5));
console.log(".........end..........");

setTimeout(function(){

    obj.sign = 'a**b'; 
    obj.info.name = '一二三';
    console.log('\n****update info ****');
    console.log('obj: ', JSON.stringify(obj));
    console.log('obj2: ', JSON.stringify(obj2));
    console.log('obj3: ', JSON.stringify(obj3));
    console.log('obj4: ', JSON.stringify(obj4));
    console.log('obj5: ', JSON.stringify(obj5));
    console.log(".........end..........");
},100);

/*
打印日志结果:
obj:  {"info":{"name":"大锤"},"sign":"xxx"}
obj2:  {"info":{"name":"大锤"},"sign":"xxx"}
obj3:  {"info":{"name":"大锤"},"sign":"xxx"}
obj4:  {"info":{"name":"大锤"},"sign":"xxx"}
obj5:  {"info":{"name":"大锤"},"sign":"xxx"}
.........end..........

****update info ****
obj:  {"info":{"name":"一二三"},"sign":"a**b"}   //只拷贝了第一级属性
obj2:  {"info":{"name":"一二三"},"sign":"xxx"}   //只拷贝了第一级属性
obj3:  {"info":{"name":"一二三"},"sign":"xxx"}   //只拷贝了第一级属性
obj4:  {"info":{"name":"大锤"},"sign":"xxx"}     //全部层级深拷贝
obj5:  {"info":{"name":"大锤"},"sign":"xxx"}    //全部层级深拷贝

*/


//二、测试数组的深拷贝
setTimeout(function(){
    console.log('\n\n.....数组的深拷贝测试....');
    var arr = [{name: '小明'}, true, 18];
    var arr2 = Object.assign([], arr);
    var arr3 = [...arr2];
    var arr4 = deepCloneObj(arr);
    var arr5 = JSON.parse(JSON.stringify(arr));

    console.log('arr: ', JSON.stringify(arr));
    console.log('arr2: ', JSON.stringify(arr2));
    console.log('arr3: ', JSON.stringify(arr3));
    console.log('arr4: ', JSON.stringify(arr4));
    console.log('arr5: ', JSON.stringify(arr5));
    console.log("......end......\n");

    setTimeout(function(){

        arr[0].name = '五六七', arr[1] = false, arr[2] = 99;
        console.log('arr: ', JSON.stringify(arr));
        console.log('arr2: ', JSON.stringify(arr2));
        console.log('arr3: ', JSON.stringify(arr3));
        console.log('arr4: ', JSON.stringify(arr4));
        console.log('arr5: ', JSON.stringify(arr5));

    }, 100);
    
    /*
    数组测试打印日志结果:
    .....数组的深拷贝测试....
    arr:  [{"name":"小明"},true,18]
    arr2:  [{"name":"小明"},true,18]
    arr3:  [{"name":"小明"},true,18]
    arr4:  [{"name":"小明"},true,18]
    arr5:  [{"name":"小明"},true,18]
    ......end......

    arr:  [{"name":"五六七"},false,99]
    arr2:  [{"name":"五六七"},true,18]    //只拷贝了第一级属性
    arr3:  [{"name":"五六七"},true,18]   //只拷贝了第一级属性
    arr4:  [{"name":"小明"},true,18]    //全部层级深拷贝
    arr5:  [{"name":"小明"},true,18]   //全部层级深拷贝
    */

},1000);
View Code

 

二、网络图片转成base64, 在线图片或文件点击下载(隐藏连接)
es6

<div>
            <div onclick="clickMeDownload()">点我下载</div>
            
            <script type="text/javascript">
                /**
                 * 根据远程图片转成base64数据 (远程图片和当前页面不是同一域名时,须要进行web服务器配置,使其能够跨域下载)
                 * @param url      图片连接
                 * @param callback 回调函数
                 */
                function getBase64ByImgUrl(url, callback){
                    let canvas = document.createElement('canvas'),
                        ctx = canvas.getContext('2d'),
                        img = new Image;
                    img.crossOrigin = 'Anonymous';
                    img.onload = function(){
                        canvas.height = img.height;
                        canvas.width = img.width;
                        ctx.drawImage(img,0,0);

                        //获取base64数据
                        let base64 = canvas.toDataURL('image/png');
                        //回调
                        if (callback){
                            callback(base64);
                        }
                        canvas = null;
                    }
                    img.src = url;
                }

                /**
                 * 把base64转成文件流
                 * @param base64     base64数据
                 * @param filename   自定义文件的名字
                 */
                function getFileByBase64(base64, filename){

                    let arr = base64.split(','), mime = arr[0].match(/:(.*?);/)[1],
                        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);

                    while(n--){
                        u8arr[n] = bstr.charCodeAt(n);
                    }

                    return new File([u8arr], filename, {type:mime});
                }


                /**
                 * 测试例子:点击下载,隐藏下载连接
                 */
                function clickMeDownload(){

                    let imgUrl = 'https://img2018.cnblogs.com/blog/454511/201811/454511-20181114115022054-611805083.png';

                    getBase64ByImgUrl(imgUrl, function(base64){
                        console.log(base64);

                        //建立a标签, 设置a标签的href属性和download属性
                        var aEle = document.createElement('a');
                        aEle.setAttribute('href', base64);
                        aEle.setAttribute('download', 'temp.png');
                        aEle.style.display = 'none'; //隐藏a标签
                        document.body.appendChild(aEle);  //将a标签添加到body里
                        aEle.click();    //触发a标签点击事件

                        document.body.removeChild(aEle);  //下载图片后,移除a标签

                    });
                }
            </script>
        </div>
View Code

 

三、经常使用CSS样式记录web

3.1 给定标签宽高,内容超出限制宽高后,以省略点展现,示例:canvas

<div class="text-box">宽度500px, 高度50px,超出高度后后缀...展现。这俩人是现今世上,手段最高明的摸金校尉,都有万夫不挡之勇,神鬼莫测之机,兼有云长之忠,翼德之猛,子龙之勇,孔明之智,那面古镜必定就是他们从云南掏出来的。</div>
View Code
/* 六、超出限制宽高后省略点展现
            多行后显示省略点,只应用于-webkit内核; 移动端浏览器基本都是WebKit内核的,因此该样式适用于移动端
        */
        .text-box{
            margin-top: 20px; width: 500px; height: 50px; border:1px dashed #999; color: #999; line-height: 25px;
            overflow: hidden; text-overflow: ellipsis; display: -webkit-box;
            -webkit-line-clamp: 2; /* 这个是设置最多展现几行 */
            -webkit-box-orient: vertical; word-break:break-all;
        }
View Code

3.2  一个标签,配合before和after属性,设置出外圆边框,内三角形图标跨域

<span class="video-icon"></span>
/* 五、视屏图标icon */
        .video-icon { display: inline-block; width: 30px; height: 30px; border: 2px solid blue; border-radius: 30px; position: relative; cursor: pointer; }
        .video-icon:after {
            position: absolute; left: 12px; top: 7px; content: '';
            border-width:8px 0 8px 10px; border-style:solid;
            border-color:transparent transparent transparent blue;
        }
View Code

3.3  单选切换:两个按钮,只能选中一个,左边按钮的左边和右边按钮的右边圆角数组

<div class="grade_box"><div class="grade_first grade_sel">一级分类</div><div class="grade_second">二级分类</div></div>
        <script type="text/javascript">
            var gradeList = (document.getElementsByClassName('grade_box')[0]).children;

            for (var i = 0; i < gradeList.length; i++){
                var obj = gradeList[i];

                obj.setAttribute('index', i);

                obj.onclick = function(){
                    var index = this.getAttribute('index');

                    console.log(this);

                    if (index == 0){
                        gradeList[0].className = 'grade_first grade_sel';
                        gradeList[1].className = 'grade_second';
                    }
                    else{
                        gradeList[0].className = 'grade_first';
                        gradeList[1].className = 'grade_second grade_sel';
                    }
                }
            }
        </script>
View Code
.grade_box { width: 300px; height: 40px; }
        .grade_box div {
            display: inline-block; height: 100%; width: 50%; line-height: 40px; text-align: center; background-color: #f4f4f4; color: #ff7800; border: 1px solid #ff7800; box-sizing: border-box; cursor: pointer;
        }
        .grade_box .grade_sel { background-color: #ff7800; color: #fff; }
        .grade_box .grade_first { border-top-left-radius: 40px; border-bottom-left-radius: 40px; }
        .grade_box .grade_second { border-top-right-radius: 40px; border-bottom-right-radius: 40px; }
View Code

3.4 按钮背景颜色渐变浏览器

<div class="bg_change_btn">四、按钮背景颜色渐变</div>
.bg_change_btn{
            width: 200px; height: 50px; line-height: 50px; border-radius: 50px; margin-top: 30px; text-align: center;
            background-image: linear-gradient(-45deg, orange 0%, yellow 100%), linear-gradient( green, black); cursor: pointer;
        }
View Code

 

四、JS中某些数字加减乘除会出现多位小数点现象,精度丢失,举例:服务器

console.log("0.1+0.2 = ", 0.1+0.2);   //0.1+0.2 =  0.30000000000000004
console.log("0.1+0.7 = ", 0.1+0.7);   //0.1+0.7 =  0.7999999999999999
console.log("0.2+0.7 = ", 0.2+0.7)    //0.2+0.7 =  0.8999999999999999
console.log("1.1+0.3 = ", 1.1+0.3)    //1.1+0.3 =  1.4000000000000001

console.log("1.7-0.1 = ", 1.7-1.1);   //1.7-0.1 =  0.5999999999999999
console.log("1.7-1.2 = ", 1.7-1.3);   //1.7-1.2 =  0.3999999999999999
console.log("1.7-1.4 = ", 1.7-1.4);   //1.7-1.4 =  0.30000000000000004

console.log("1.10*100 =", 1.10*100);  //1.10*100 = 110.00000000000001
console.log("1.11*100 =", 1.11*100);  //1.11*100 = 111.00000000000001
console.log("1.12*100 =", 1.12*100);  //1.12*100 = 112.00000000000001
console.log("1.13*100 =", 1.13*100);  //1.13*100 = 112.99999999999999
console.log("1.14*100 =", 1.14*100);  //1.14*100 = 113.99999999999999
console.log("1.15*100 =", 1.15*100);  //1.15*100 = 114.99999999999999
console.log("1.16*100 =", 1.16*100);  //1.16*100 = 115.99999999999999

console.log("0.7/0.1 = ", 0.7/0.1);   //0.7/0.1 =  6.999999999999999
console.log("0.6/0.1 = ", 0.6/0.1);   //0.6/0.1 =  5.999999999999999

解决方式1,使用Math.round函数处理,假设数字变量名为num, 格式为:Math.round(num*100) / 100:网络

console.log("0.1+0.2 = ", Math.round((0.1+0.2)*100)/100);   //0.1+0.2 =  0.3
console.log("0.1+0.7 = ", Math.round((0.1+0.7)*100)/100);   //0.1+0.7 =  0.8
console.log("0.2+0.7 = ", Math.round((0.2+0.7)*100)/100)    //0.2+0.7 =  0.9
console.log("1.1+0.3 = ", Math.round((1.1+0.3)*100)/100)    //1.1+0.3 =  1.4

console.log("1.7-0.1 = ", Math.round((1.7-0.1)*100)/100);   //1.7-0.1 =  1.6
console.log("1.7-1.2 = ", Math.round((1.7-1.2)*100)/100);   //1.7-1.2 =  0.5
console.log("1.7-1.4 = ", Math.round((1.7-1.4)*100)/100);   //1.7-1.4 =  0.3

console.log("1.10*100 =", Math.round((1.10*100)*100)/100);  //1.10*100 = 110
console.log("1.11*100 =", Math.round((1.11*100)*100)/100);  //1.11*100 = 111
console.log("1.12*100 =", Math.round((1.12*100)*100)/100);  //1.12*100 = 112
console.log("1.13*100 =", Math.round((1.13*100)*100)/100);  //1.13*100 = 113
console.log("1.14*100 =", Math.round((1.14*100)*100)/100);  //1.14*100 = 114
console.log("1.15*100 =", Math.round((1.15*100)*100)/100);  //1.15*100 = 115
console.log("1.16*100 =", Math.round((1.16*100)*100)/100);  //1.16*100 = 116

console.log("0.7/0.1 = ", Math.round((0.7/0.1)*100)/100);   //0.7/0.1 =  7
console.log("0.6/0.1 = ", Math.round((0.6/0.1)*100)/100);   //0.6/0.1 =  6

 

解决方式2:使用parseInt函数,假设数字变量名为num, 格式为:parseInt(num*100 + 0.1)/100

console.log("0.1+0.2 = ", parseInt((0.1+0.2)*100+0.1)/100);   //0.1+0.2 =  0.3
console.log("0.1+0.7 = ", parseInt((0.1+0.7)*100+0.1)/100);   //0.1+0.7 =  0.8
console.log("0.2+0.7 = ", parseInt((0.2+0.7)*100+0.1)/100)    //0.2+0.7 =  0.9
console.log("1.1+0.3 = ", parseInt((1.1+0.3)*100+0.1)/100)    //1.1+0.3 =  1.4

console.log("1.7-0.1 = ", parseInt((1.7-0.1)*100+0.1)/100);   //1.7-0.1 =  1.6
console.log("1.7-1.2 = ", parseInt((1.7-1.2)*100+0.1)/100);   //1.7-1.2 =  0.5
console.log("1.7-1.4 = ", parseInt((1.7-1.4)*100+0.1)/100);   //1.7-1.4 =  0.3

console.log("1.10*100 =", parseInt((1.10*100)*100+0.1)/100);  //1.10*100 = 110
console.log("1.11*100 =", parseInt((1.11*100)*100+0.1)/100);  //1.11*100 = 111
console.log("1.12*100 =", parseInt((1.12*100)*100+0.1)/100);  //1.12*100 = 112
console.log("1.13*100 =", parseInt((1.13*100)*100+0.1)/100);  //1.13*100 = 113
console.log("1.14*100 =", parseInt((1.14*100)*100+0.1)/100);  //1.14*100 = 114
console.log("1.15*100 =", parseInt((1.15*100)*100+0.1)/100);  //1.15*100 = 115
console.log("1.16*100 =", parseInt((1.16*100)*100+0.1)/100);  //1.16*100 = 116

console.log("0.7/0.1 = ", parseInt((0.7/0.1)*100+0.1)/100);   //0.7/0.1 =  7
console.log("0.6/0.1 = ", parseInt((0.6/0.1)*100+0.1)/100);   //0.6/0.1 =  6
View Code
相关文章
相关标签/搜索