快捷导航菜单

 

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

ES6的Object.assign函数,和{...xxx}扩展运算符能够实现浅拷贝。JSON.parse(JSON.stringify(xxx))能够实现深拷贝,但是针对要拷贝的属性值如果是函数、时间、undefined、正则表达式以及对象的原型属性和方法都无能为力。因此深拷贝需要自定义函数:

function deepClone(sourceObj){
    if (sourceObj instanceof RegExp) return new RegExp(sourceObj); //正则类型
    if (sourceObj instanceof Date) return new Date(sourceObj);    //时间类型
    if (sourceObj === null || typeof sourceObj !== 'object'){ //基础类型
        return sourceObj;
    }

    //其他引用类型数据, 找出当前数据类型的构造函数,new一个当前类型的空对象
    var obj = new sourceObj.constructor(); 
    for (var key in sourceObj){
        //属于自己的属性才递归深拷贝
        if (sourceObj.hasOwnProperty(key)){
            obj[key] = deepClone(sourceObj[key]);
        }
    }
    return obj;
}

测试代码:

//测试
function Person(name, age){
    this.name = name;
    this.age = age;
}
Person.prototype.myInfo = function(){
    console.log("my name is ", this.name, ", age is ", this.age);
}

var obj = {
    fn: Person,    //函数
    obj: new Person("王大锤", 18),  //对象
    time: new Date("2018-08-18 18:18"),  //时间
    reg: new RegExp('abc'),    //正则
    sign: undefined,    
    arr: ['etf', 99, true]
}
var obj2 = Object.assign({}, obj); //浅拷贝(ES6的Object.assign函数)
var obj3 = {...obj};               //浅拷贝(ES6扩展运算符)
//JSON.stringify深拷贝所有层级属性,但是针对属性值为函数,正则表达式,时间,undefined, 原型对象的方法和属性无能为力
var obj4 = JSON.parse(JSON.stringify(obj));       
var obj5 = deepClone(obj);

console.log("\n**************start*************")
console.log("obj: ", obj, "\n\nobj2: ", obj2, "\n\nobj3: ", obj3, "\n\nobj4: \n", obj4, "\n\nobj5: ", obj5);


obj.obj.name = '罗小虎', obj.obj.age = 27;
obj.arr.push("玉娇龙");
console.log("............update.........")
console.log("obj: ", obj, "\n\nobj2: ", obj2, "\n\nobj3: ", obj3, "\n\nobj4: \n", obj4, "\n\nobj5: ", obj5);

测试结果截图对比一下,发现使用JSON.stringify深拷贝的对象,属性值为函数和undefined的属性直接过滤不见了,然后正则表达式变成了空对象{}, 时间变成了字符串等:

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

 

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

<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

相关文章:

  • 2022-01-15
  • 2022-12-23
  • 2021-11-12
  • 2022-12-23
  • 2022-12-23
  • 2022-01-10
  • 2021-11-14
  • 2021-09-09
猜你喜欢
  • 2021-06-29
  • 2022-02-27
  • 2022-12-23
  • 2022-12-23
  • 2021-12-22
  • 2021-11-27
相关资源
相似解决方案