• JavaScript对象函数基础01(对象作为引用类型,函数的创建和arguments,return,回调与递归)


    一、對象

    1.對象的創建

    var obj=new Object();//構造函數創建法
    ​
    var obj={};//字面量創建法
    ​
    var obj=Object.create({})

    2.鍵值對

    對象key只能是字符類型

    var a="keys";
    var obj={
        //key:value
        name:"xietian",
        //"name":"xietian"//字符型key
        [a]:16,//變量型key 
        5:10
    }
    console.log(obj.name);
    console.log(obj.keys);
    console.log(obj.5);//點語法拒絕使用非字符類型
    console.log(obj[5]);//在對象中key除了字符類型以外只能支持symbol類型,這裏的5隱式轉換成了字符
    ​
    var o={
        a:1
    }
    var o1={
        b:2
    }
    var obj={};
    var arr=[1,2,3];
    var arr1=[4,5,6];
    obj[o]=10;//因爲對象的屬性名必須為字符類型,隱式轉換,所以不管什麽對象都爲[object Object] 10
    obj[undefined]=20;//undefined:20
    obj[null]=30;//null:30
    obj[arr]=40;//1,2,3:40
    console.log(obj[arr1]);//undefined 爲什麽以後學
    console.log(obj[o1]);//對象轉換成字符串了[object Object],結果為10
    console.log(String(o));//[object Object]
    console.log(obj);
    //key如果不是字符串,不能使用.語法

    3.對象引用

    //對象引用存儲
    //對象存儲在堆中
    //對象打印時遇到的數據問題
    var obj={
        a:1
    }
    console.log(obj);//直接打印是點開以後是{a:10}
    obj.a=10;
    ​
    ​
    //a的值不會改變
    //JSON將對象轉換成字符串
    console.log(String(obj));//[object Object]
    var str=JSON.stringify(obj);
    //JSON格式字符串
    //'{"a":1,"b":2,"c":"xietian","checked":true}'
    console.log(str);//{a:1}
    obj.a=10;
    //將JSON格式字符串轉換為對象
    var o=JSON.parse(str);
    console.log(o);
    //{a:1}
    ​
    //對象的引用關係
    var obj={
        a:1
    }
    var obj1=obj;
    obj.a=100;
    console.log(obj1.a);//100
    //obj和obj1的值都是一樣的引用地址,所以改變一個對象的内容時,同時改變
    ​
    var o={a:1};
    var o1=o;
    o1.n=o={b:3};
    //求o1和o的值
    //分兩步,先把值賦給最左邊的o1.n,在把值賦給o
    //o1.n為{a:1},由第二句var o1=o; o1為{a:1,n:{a:1}}
    //o為o{b:3}
    ​
    var o={a:1};
    var o1={a:1};
    console.log(o===o1);//判斷對象是否相等,僅判斷地址,而不是判斷對象内容false
    console.log(JSON.stringify(o)===JSON.stringify(o1));//有漏洞,有可能出錯true

    4.垃圾回收機制

    obj=null;在堆中對應的内容的引用列表被刪除,儅別的東西占用内存達到峰值時,垃圾回收機制

    // 垃圾回收机制 在堆中的对象可能被若干个变量引用其地址,如果这个对象在后面的内容中不再使用,我们需要将堆中的这个对象清除,否则,不会被浏览器自动清除,这样就会造成垃圾产生,当不断产生这种垃圾时,我们就把这种情况叫内存泄漏

    // 如何处理内存泄漏 先创建每个对象的管理池,针对每个对象所引用它的变量做统一存储管理,如果 需要清理该对象时,将引用它的所有变量设置为null,当内存上限达到峰值时,系统 会通过垃圾回收车将这些堆中无引用的对象全部清除回收,这就是垃圾回收机制

    5.對象的遍歷和複製

    //遍歷對象(使用for in)
    var obj={
        c:3,
        d:4,
        e:5,
        f:{
            a:1,
            b:2,
            c:3
        }
    }
    for(var prop in obj){
        console.log(prop,obj[prop])
    }
    console.log(obj);
    //沒有先後順序,對象遍歷通過添加屬性的先後順序遍歷的
    ​
    var obj1={};
    for(var prop in obj){
        console.log(prop);
        obj1[prop]=obj[prop];
    }
    obj.a=10;
    console.log(obj1);//沒有引用關係,對象複製c d e f然後打印原obj一樣的對象,obj後來增加的屬性值對obj1沒有影響
    ​
    //對象的深複製
    var obj1=JSON.parse(JSON.stringify(obj));//不能複製對象的方法,只是複製對象裏的值,沒有引用關係,obj後來增加的屬性值對obj1沒有影響
    obj.f.a=100;
    console.log(obj,obj1);
    ​
    //不可枚舉屬性__proto__,對象的方法
    var obj={
        a:1,
        b:true,
        c:function(){
            
        }
    }
    // JSON方法不可以将对象中方法进行转换
    var str=JSON.stringify(obj);
    console.log(str);
    ​
    var obj={
        a:{
            a:1
        },
        b:{
            c:2
        }
    }
    var o=obj.a;//把obj.a的地址賦給o
    var o1=obj.b;
    o.a=10;//改變地址内的屬性值
    o={c:1};//改變地址,覆蓋了之前的obj.a的那個對象
    console.log(obj,o);//{a:{a:10},b:{c:2}};{c:1}
    ​
    // 删除属性
    var obj={
         a:1,
         b:2
    }
    delete obj.a;
    console.log(obj);

    二、函數

    1.函數的創建

    //函數是一個對象,存儲在堆中
    1.function fn1(arg1,arg2){//函數的聲明
        //函數語句塊
        console.log("a");
    }
    fn1();//函數的執行
    //函數是一個對象,這種普通函數的創建,在script被執行時就被放入堆中,并且在棧中以函數名作爲變量引用到堆中這個函數地址
    //函數可以創建在當前script的任意位置,都可以調用,在這個script之前的script引入不了
    //函數在創建時就創建這個函數名的變量,因爲是全局的,所以就會被污染覆蓋
    //覆蓋前仍然可以執行當前函數,覆蓋后,函數不能夠執行了
    ​
    fn1();
    //如果函數中沒有使用return關鍵詞,函數返回一個undefined值
    console.log(fn1());//a undefined
    console.log(fn1);//返回這個函數
        ƒ fn1(arg1,arg2){
            //函數語句塊
            console.log("a");
        }
    console.dir(fn1);//将这种对象以对象形式展现 f fn1(arg1,arg2)裏面是這個函數的對象形式的結構
    ​
    fn1.a=10;//fn和fn1添加了一個對象的屬性a:10
    var fn=fn1;//函数是a:10对象,因此局部引用关系
    fn();//a
    ​
    2.匿名函數創建方式
    fn2();//這裏調用會報錯
    var fn2=function(){
        //匿名函數創建,創建好的匿名函數賦值給fn2這個變量
        //變量什麽時候定義,這個變量才能在棧中產生,才可以被調用
        console.log("aaa");
    }
    fn2();//aaa
    ​
    //在对象中,可以设置一个属性是一个函数,这样就给了对象定义了一个方法
    var bn=document.getElementById("bn");
    bn.onclick=function(){
        console.log("aa");
        bn.onclick=null;//執行一次就把這個函數刪除
    }
    ​
    (function(){
        console.log("aa");
        //會自動執行,以後永遠不能再調用
    })();
    ​
    3.構造函數創建函數
    // 构造函数创建,每个参数都必须是字符串
    // 除了最后一个参数是函数的语句块以外,前面所有的参数都是该函数的参数
    var fn=new Function("a","b","console.log(a+b)");
    function fn(a,b){
        console.log(a+b);
    }
    fn(3,4);
    //第三种方式我们不推荐,因为这种语法会导致解析两次代码(第一次解析常规JS代码,第二次是解析传入构造函数中的字符串),从而影响性能,但我们可以通过这种语法来理解函数是对象,函数名是指针的概念。
    ​
    //函數的刪除
    bn.onclick=null;//匿名函數刪除
    delete obj.function//對象下的方法刪除

    2.函數的參數

    在函数后面括号中填写的变量叫做参数,为什么要填写参数?函数如果没有参数,参数目的是解决函数在不同清空下解决不同问题

    //  在设计函数时,尽量不要让函数内部与外部有关联
    ​
    // 尽量让函数内部是一个独立的个体
    ​
    // 抽象function fn(a, b) {}
    function createTable(row, col) {
        var str = "<table>";
        for (var i = 0; i < row; i++) {
            str += "<tr>";
            for (var j = 0; j < col; j++) {
               str += "<td></td>";
            }
            str += "</tr>";
        }
        str += "</table>";
        document.body.innerHTML += str;
    }
    createTable(3, 10);//3行10列的列表
    createTable(5, 10);
    createTable(6, 8); 
    ​
    function fn1(a,b){
        var s=a+b;
        console.log(s);
    }
    function fn2(a,b){
        var s=a-b;
        console.log(s);
    }
    function fn3(a,b){
        var s=a*b;
        console.log(s);
    }
    function fn4(a,b){
        var s=a/b;
        console.log(s);
    }
    function fns(a,b,type){
       var s;
       switch(type){
          case "+":
          s=a+b;
          break;
          case "-":
          s=a-b;
          break;
          case "*":
          s=a*b;
          break;
          case "/":
          s=a/b;
          break;
       }
    console.log(s);
    }
    fns(3,5,"*");
    fn1(3,5);
    fn3(3,5); 
    ​
    //在js中,因为js是一种弱类型语言,因此不能对参数约束其类型
    // 这就会造成,因为使用函数者输入的参数不符合需求而造成代码出错,无法通过白盒测试
    function fn4(a,b){
       if(isNaN(a) || isNaN(b)) return "输入参数错误";
       if(b===0) return "除数不能为0";
       var s=a/b;
       return s;
    }
    var s=fn4(3,5);
    console.log(s); 
    ​
    // ES5版本中 js中参数不能设置初始值,不填写参数就是undefined
    // 这个函数定义时的参数叫做形参
    function fn5(a,b,c,d){
       console.log(a,b,c,d);
    } 
    // 这里执行时填入的参数叫做实参,实参是按照形参顺序一一赋值给形参
    // 如果实参数量小于形参数量,后面的形参值就是undefined
    // fn5(1,2,4);

    3.arguments的使用

    // 定义函数时没有定义参数
    // 如果实参数量大于形参数,使用arguments
    // arguments只能出现在函数语句块中
    // 用于当前函数的参数不固定数量
    function fn1(){
        console.log(arguments);
        console.log(arguments[0],arguments[1])
    } 
    ​
    // 当执行函数时传入实参
    // fn1(3,4,5,6);
    ​
    function sum(){
        var s=0;
        for(var i=0;i<arguments.length;i++){
            s+=arguments[i];
        }
        console.log(s);
    }
    sum(3,4);//7
    sum(3,4,5);//12
    sum(3,4,5,6); //18
    ​
    function max(){
        if(arguments.length===0) return "没有值";
        // if(arguments.length===1) return arguments[0];
        var s=arguments[0];
        for(var i=1;i<arguments.length;i++){
            s=s>arguments[i] ? s : arguments[i];
        }
        return s;
    }
    ​
    var x=max(1,4,7);//7
    ​
    var x= max(3);//3
    console.log(x); 
    ​
    function fn1(){
        //console.log(arguments.callee);//当前函数
        //console.log(arguments.callee.name);//当前函数的名字fn1
        console.log(arguments.callee.caller);//调用当前函数的外部函数
    }
    ​
    function fn2(){
        fn1();
    }
    ​
    function fn3(){
        fn1();
    }
    ​
    fn2();//ƒ fn2(){
                fn1();
              }
    fn3(); //ƒ fn3(){
                fn1();
             }
    ​
    var i=0;
    (function(){
        i++;
        console.log(i);
        if(i<5) arguments.callee();//執行當前匿名立即執行函數,打印結果1 2 3 4 5
    })(); 

    4.變量作用域

    // 变量只能在局部中使用,因此叫做局部变量
    // 在任何地方都可以使用的变量叫做全局变量
    var a=10;
    function fn(){
        // 被定义在函数内部的变量,使用范围仅在函数内部
        // 并且当前函数执行完成以后,这个变量会被销毁
        // 下一次这个函数再执行时,会重新定义这个变量
        // 并且变量不能被保存在函数执行完成后还能使用
        var a=1;
        console.log(a);//优先局部变量
        // console.log(a+window.a)//ES6被禁止
    }
    fn(); //1
    console.log(a);//10
    ​
    var a=10;
    function fn(){
        // 如果当前函数内没有定义与全局变量相同的局部变量名
        // 这里直接调用全局变量
        console.log(a);
    }
    fn();//10
    ​
    ​
    var a=10;
    function fn(){
        var a;
        console.log(a);//遵照局部变量优先原则
    }
    fn(); //undefined
    ​
    var a=10;
    function fn(){
        //打印变量早于定义该局部变量之前,打印undefined
        console.log(a);//任然遵照局部变量优先原则
        var a=4; 
    }
    fn(); //undefined
    ​
    // 在函数中只要看到使用var定义的变量,这个变量就一定是局部变量,而且这个变量被优先
     
    var a=10;
    function fn(){
        console.log(a);//这里没有使用var,当前a是全局的
        a=4; 
    }
    fn(); //10
    ​
    ​
    var a=10;
    function fn(a){
        // 当在函数中设置了参数,
        // 那么就相当于,这个参数就是被var定义好的局部变量
        console.log(a);
    }
    fn(5);//5
    ​
    console.log(a); //10
    ​
    var a=100;
    function fn(a){
        console.log(a);//6
        var a;//因为参数本身就是局部变量,所以重新定义不赋值不起作用,參數優先于局部變量
        console.log(a);//6
        a=10;
        console.log(a);//10
    }
    fn(6); 
    ​
    var a;
    function a(a){
        console.log(a);//6
        var a;
        console.log(a);//6
        a=10;
        console.log(a);//10
    }
    ​
    a(6);//可以执行
    a=100;//改變了函數a,所以下一步報錯
    a(6);//报错 
    ​
    var a;
    function a(a,a){
        console.log(a);//7
        var a;
        console.log(a);//7
        a=10;
        console.log(a);//10
    }
    ​
    a(6,7);//可以执行
    a=100;
    a(6,7);//报错 
    ​
    ​
    var a={
        a:function(a){
            var a;
            console.log(a);
        }
    }
    ​
    a.a(5); //5
    ​
    function fn(f){
        var x=20;
        f(x);//x=20作爲實參傳給了fn1(x),此處x是實參
    }
    ​
    function fn1(x){//此處x是形參
        console.log(x);
    }
    ​
    fn(fn1); //20
    ​
    var name = 'World!';
    (function () {
        if (typeof name === 'undefined') {
            var name = 'Jack'//因爲在函數内部,不關if else的事
            console.log(name)
        } else {
        console.log(name)
        }
    })()//Jack

    5.return

    function fn(a,b){
       // if(arguments.callee.length<arguments.length)
       console.log(arguments.length);//实参的长度,也就是实际传入的参数长度
    }
    fn(1,2,3,4);
    console.log(fn.length);//形参长度,就是函数定义参数数量
    ​
    fn=null;  清除函数
    function fn(){
    ​
    }
    delete window.fn;//无效
    ​
    // 函数在执行时,将返回函数中return 内容
    // 如果return 后没有内容或者没有return ,返回一个undefined
    function fn(){
        return 1;1
    }
    function fn1(){
         return 2;
    }
    ​
    var s=fn();//
    console.log(s);
    ​
    var s=fn()+3;//4
    var s=fn()+fn1();//3
    ​
    函数返回的作用
    1、返回局部变量
    function fn(){
        var a=1;
        a+=3;
        return a;
    } 
    ​
    function fn(_name,_sex){//返回對象
        var obj={
            name:_name,
            sex:_sex,
        }
        return obj;
    } 
    ​
    function fn(_name,_sex){
       return {
           name:_name,
           sex:_sex,
       }
    }
    ​
    var obj=fn("xietian","男");
    var obj1=fn("zhangsan","男");
    console.log(obj,obj1);
    ​
    function fn(){
        var fn1=function(){
            console.log("aa");
        }
        return fn1;//返回函數
    } 
    ​
    function fn(){
       return function(){
          console.log("aa");
       }
    }
    ​
    var f=fn();
    f();//aa
    ​
    2、返回参数
    function fn(a,b){
        a+=b;
        return a;
    }
    ​
    var a=10;
    var b=20;
    fn(a,b);
    console.log(a); //10
    ​
    function fn(obj){
        obj.a=10;
        return obj;
    }
    var obj={
        a:1
    }
    var  obj1=fn(obj);//obj變成了{a:10}
    console.log(obj===obj1); //true
    ​
    ​
    3、跳出,切断,不继续执行
    function fn(a,b){
        if(isNaN(a) || isNaN(b)) return;
        console.log("是数值");
    }
    fn(3,5); //是數值
    ​
    var sum=fn(3,5,"*");
    console.log(sum);//是數值 undefined
    ​
    function fn(a,b,type){
        if(isNaN(a) || isNaN(b)) return "错误的数字";
        switch(type){
            case "+":return fn1(a,b);
            case "-":return fn2(a,b);
            case "*":return fn3(a,b);
            case "/":return fn4(a,b);
            default:
            return "错误的符号";
        }
    }
    ​
    function fn1(a,b){
        return a+b;
    }
    function fn2(a,b){
        if(a<0) a=0;
        return a-b;
    }
    function fn3(a,b){
        return a*b;
    }
    function fn4(a,b){
        if(b===0) return "错误除数";
        return a/b;
    }
    ​
    ​
    function fn1(a,b){
        var s=a+b;
        console.log(s);
    }
    function fn2(a,b){
        var s=a-b;
        console.log(s);
    }
    function fn3(a,b){
        var s=a*b;
        console.log(s);
    }
    function fn4(a,b){
        var s=a/b;
        console.log(s);
    }
    ​
    function fns(a,b,type){
        var s;
        switch(type){
            case "+":
            s=a+b;
            break;
            case "-":
            s=a-b;
            break;
            case "*":
            s=a*b;
            break;
            case "/":
            s=a/b;
            break;
        }
    console.log(s);
    } 
    ​
    var str="零一二三四五六七八九十";
    console.log(str[5]);
    var s=30;//"三十";
    var s=29;//"二十九";
    var s=16;//"十六";
    //切断跳出
    function changeCN(num){
        if(isNaN(num)) return "这不是一个数字";
        if(num>=100 || num<0) return "不是范围内的数字";
        num=parseInt(num);
        if(num<11) return str[num];
        if(num<20) return "十"+str[num%10];
        if(num%10===0) return str[num/10]+"十";
        return str[parseInt(num/10)]+"十"+str[num%10];
    }
    console.log(changeCN(96)); //九十六
    ​
    function fn1(){
        console.log("a");
        fn2();
        console.log("c");
    }
    ​
    function fn2(){
        console.log("b");
        fn3();
        console.log("d");
    }
    ​
    function fn3(){
        return console.log("e");
    }
    ​
    fn1(); // a b e d c
    ​
    function fn1(a){
        if(a===1) return fn2();
        if(a===2) return fn3();
        if(a===3) return fn4();
        if(a===4) return fn5();
        var s=0;
        switch(a){
            case 1: s+=fn2();
            case 2: s+=fn3();
            case 3: s+=fn4();
            case 4: s+=fn5();
        }
        return s;
    }
    ​
    function fn2(){
        console.log(1)
        return 10;
    }
    function fn3(){
        console.log(2)
        return 20;
    }
    function fn4(){
        console.log(3)
        return 30;
    }
    function fn5(){
        console.log(4)
        return 40;
    }
    var s=fn1(3);
    console.log(s); //3 30
    ​
    //函数执行中执行其他函数,另一个函数中的内容执行完成后才会继续执行当前函数
    // 当需要并列执行多个时,我们可以在一个函数中统一调配执行的顺序

    三、回調

    function fn1(fn){
        fn();
    }
    ​
    function fn2(){
        console.log("aaa");
    }
    ​
    fn1(fn2); //aaa
    // 将一个函数以参数的形式传入到另一个函数中,并且在那个函数执行
    ​
    var i=0;
    ​
    fn1();//3 3 3
    ​
    function fn1(){
        i++;
        if(i<3) fn2();
        console.log(i);
    }
    ​
    // 函数内执行当前自身函数
    ​
    function fn2(){
        i++;
        if(i<3) fn3();
        console.log(i);
    }
    function fn3(){
        i++;
        if(i<3) fn4();
        console.log(i);
    }
    ​
    //    不被执行
    function fn4(){
        i++;
        if(i<3) fn1();
        console.log(i);
    }  
    ​
    //根据内存大小设置递归上限的次数,如果递归次数太多,就会堆栈上限溢出
    //Uncaught RangeError: Maximum call stack size exceeded
    var i=0;
    ​
    fn1();
    ​
    function fn1(){
        i++;
        if(i<20000) fn1();
        // console.log(i);
    } 
    ​
    // 回调:
    // 1、回调一般用于当处理某件事情需要等待时,设置回调
    // 2、当不需要关心具体后续需要处理的事情时,设置回调
    ​
    // setTimeout(超时执行的函数,超时时间,执行函数的参数)  返回一个id数
    console.log("a");
    var id=setTimeout(fn,2000,5);//异步,一定时间后处理问题
    ​
    function fn(n){
        console.log(n);
        clearTimeout(id);//清除这个超时函数
    }
    console.log("b"); //a b 2s之後打印5
    ​
    var id=setInterval(fn,2000);
    var num=0;
    function fn(){
        num++;
        console.log("aa");
        if(num>3) clearInterval(id);
    } 
    ​
    ​
    function fns(a,b,fn){
        if(isNaN(a) || isNaN(b)) return "错误的数据";
        return fn(a,b);
    }
    ​
    function fn1(a,b){
        return a+b;
    }
    function fn2(a,b){
        if(a<0) a=0;
        return a-b;
    }
    function fn3(a,b){
        return a*b;
    }
    function fn4(a,b){
        if(b===0) return "错误除数";
        return a/b;
    }
    ​
    var s=fns(3,5,fn3);
    console.log(s); //15
    ​
    // 红绿灯
    var id;
    function setLight() {
        arguments[0](arguments[1], arguments[2]);
    }
    function redLight(fn, fn2) {
        clearTimeout(id);
        console.log("红灯");
        id = setTimeout(fn, 2000, fn2, arguments.callee);
    }
    function yellowLight(fn, fn2) {
        clearTimeout(id);
        console.log("黄灯");
        id = setTimeout(fn, 2000, fn2, arguments.callee);
    }
    function greenLight(fn, fn2) {
        clearTimeout(id);
        console.log("绿灯");
        id = setTimeout(fn, 2000, fn2, arguments.callee);
    }
    ​
    setLight(yellowLight, redLight, greenLight); 
    ​
    //回调函数完成循环局部传参返回值
    function fn1(fn, i, sum) {
        if (i === undefined) (i = 1), (sum = 1);
        i++;
        if (i > 100) {
            return sum;
        }
        return fn(arguments.callee, i, sum);
    }
    function fn2(fn, i, sum) {
        sum += i;
        return fn(arguments.callee, i, sum);
    }
    function fn3(fn, i, sum) {
        sum *= i;
        return fn(arguments.callee, i, sum);
    }
    var sum = fn1(fn3);
    console.log(sum);//9.33262154439441e+157

    四、遞歸

    <div>
        <div id="div0">
            <span id="span0"></span>
            <span></span>
            <span id="span1"></span>
            <ul>
                <li id="li0"></li>
                <li></li>
                <li id="li1"></li>
                <li id="li2"></li>
                <li id="li3"></li>
            </ul>
        </div>
        <div id="div1">
            <ul>
                <li></li>
                <li id="li4"></li>
                <li>
                    <a href="#" id="a0"></a>
                </li>
                <li id="li5"><a href="#"></a></li>
                <li><a href="#" id="a1"></a></li>
                <li id="li6"></li>
            </ul>
        </div>
         <p id="p0"></p>
         <p id="p1">
             <div id="div2"></div>
             <div></div>
             <div><a href="#"></a></div>
             <div id="div3"></div>
         </p>
         <p id="p2"></p>
         <p id="p3">
             <span></span>
             <span id="span2"></span>
             <span><a href="#"></a></span>
             <span id="span3"></span>
             <span id="span4"></span>
         </p>
     </div>
     <script>
          console.log(document.body.children)
          function getDOMObj(parent,obj){
                obj=obj || {};
                parent=parent || document.body;
                if(parent.id) obj[parent.id]=parent;
                for(var i=0;i<parent.children.length;i++){
                    getDOMObj(parent.children[i],obj);
                }
                return obj;
           }
    ​
           var obj=getDOMObj();
           console.log(obj); 
    ​
           var obj={
                a:1,
                b:2,
                c:{
                    a:1,
                    b:2,
                    c:{
                        a:1,
                        b:2,
                        c:{
                            a:1,
                            b:2,
                            c:3
                        }
                    }
                },
                d:{
                    a:{
                        a:1,
                        b:{
                            a:1
                        },
                        c:{
                            b:2
                        }
                    },
                    b:{
                        a:1,
                        b:{
                            c:3
                        },
                        c:{
                            d:4
                        }
                    },
                    c:{
                        a:1,
                        b:{
                            e:function(){
                                console.log("a");
                            }
                        },
                        c:{
                            
                        }
                    }
                }
           }
    ​
    ​
    var  obj1=obj;//赋值obj里面的属性发生改变,obj1里面的也会改变
    var obj1={}
    for(var prop in obj){
        obj1[prop]=obj[prop];
    }
    obj.a=10;
    obj.c.a=10;
    console.log(obj1); 
    ​
    function cloneObj(obj,target){
         target=target || {};
         for(var prop in obj){
             if(typeof obj[prop]==="object" && obj[prop]!==null){
                    target[prop]={};
                    cloneObj(obj[prop],target[prop])
             }else{
                    target[prop]=obj[prop];
             }
         }
         return target;
    }
    ​
    var obj1=cloneObj(obj);
    obj.c.a=10;
    obj.d.b.b.c=100;
    console.log(obj1); 

     

  • 相关阅读:
    使用vue做项目时,刷新页面,原本应该隐藏的东西闪一下
    input type="file" 上传文件的一些使用
    vue强制重新渲染
    元素focus页面不滚动不定位的JS处理
    js使用案例
    js使用setInterval简单实现一个时钟
    js日期封装方法
    scss简单使用总结
    JavaScript的内置对象(Global对象)
    JavaScript—Date对象详情
  • 原文地址:https://www.cnblogs.com/ananasfleisch/p/13281540.html
Copyright © 2020-2023  润新知