zoukankan      html  css  js  c++  java
  • 总结01(对象引用的赋值与对象的复制,函数作为对象及回调递归,区分数组与对象)

    一、對象

    1.使用對象作爲對象的屬性名

    會導致問題,先將對象轉換成字符串(屬性名必須為字符類型),於是所有對象都對應了這個屬性{[object Object]:10},數組不會發生這種問題,因爲數組轉換成字符串是arr=[1,2,3]->{1,2,3:10}

    2.對象的淺複製(一、5&二、7)

    對象的深複製(遞歸)比JSON.stringify(JSON.parse(obj))(不能複製函數)好

    對象的複製是爲了複製一份拷貝出來,新對象發生變化時,不會影響原對象

    3.對象的引用關係問題(對象引用的賦值)

    obj1=obj,一起改變

    只有兩個對象的引用地址相等,才===,==

    不然只有内容相等的話JSON.stringify(o)===JSON.stringify(o1)

    4.對象的遍歷for in

    5.對象的複製

    for in(複製到第一層,第二層如果有對象(因爲只是複製了對象引用地址,并不是複製原來對象的内容),會跟著變化,不能算是複製)

    var obj={
        c:3,
        d:4,
        a:1,
        b:2, 
        e:5,
        f:{
            a:1,
            b:2,
            c:{
                a:2,
                b:9
            }
        }
    }
    var obj1={};
    for(var prop in obj){
        console.log(prop);
        obj1[prop]=obj[prop];
    }
    obj.f.a=100;
    console.log(obj1,obj);//obj.f.a和obj1.f.a都變為100,所以只複製了第一層
    ​
    var obj1=JSON.parse(JSON.stringify(obj));
    obj.f.a=100;
    console.log(obj1);//obj.f.a變爲100,obj1.f.a還是1,所以是深複製
    //缺陷就是并沒有複製對象的不可枚舉屬性__proto__或者對象的方法

    二、函數

    1.函數是一個對象

    function fn1(arg1,arg2)
    {
      // 函数的语句块
      console.log("a");
    }
    console.log(fn1());
    console.log(fn1);
    console.dir(fn1);//将这种对象以对象形式展现
    fn1.a=10;
    var fn=fn1;//函数是对象,因此局部引用关系
    fn();
    //刪除函數使用刪除對象的方法fn=null,但是不能使用delete fn;

    2.在script被执行时,就放入堆中

    fn1();//可以被調用
    function fn1(arg1,arg2)
    {
      // 函数的语句块
      console.log("a");
    }
    匿名函數定義創建後才可以調用
    
    fn2();//这里调用会报错
    var fn2=function(){
        //匿名函数创建,创建好的匿名函数赋值给fn2这个变量
        //变量什么时候定义,这个变量才能在栈中产生,才可以被调用
        console.log("aaa");
    } 
    fn2();

    3.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

    4.arguments

    arguments.length實參長度

    函數名.length形參長度

    function fn1(){
        console.log(arguments);
    } 
    // 当执行函数时传入实参
    fn1(3,4,5,6);
    ​
    Arguments(4) [3, 4, 5, 6, callee: ƒ, Symbol(Symbol.iterator): ƒ]
    0: 3
    1: 4
    2: 5
    3: 6
    length: 4
    callee: ƒ fn1()
    Symbol(Symbol.iterator): ƒ values()
    __proto__: Object
    //arguments的和
    function sum(){
        var s=0;
        for(var i=0;i<arguments.length;i++){
            s+=arguments[i];
        }
        console.log(s);
    }
    //arguments最大值
    function max(){
        if(arguments.length===0)return "沒有值";
        var max=arguments[0];
        for(var i=0;i<arguments.length;i++){
            max=max>arguments[i]?max:arguments[i]
        }
        return max;
    }
    console.log(max(13,23,4243,3))
    //當前函數arguments.callee
    //調用當前函數的外部函數arguments.callee.caller

    5.變量作用域

    被定义在函数内部的变量,使用范围仅在函数内部

    并且当前函数执行完成以后,这个变量会被销毁

    在函数中只要看到使用var定义的变量,这个变量就一定是局部变量,而且这个变量被优先

    打印变量早于定义该局部变量之前,打印undefined

    var a=10;
    function fn(){
        // 打印变量早于定义该局部变量之前,打印undefined
        console.log(a);//任然遵照局部变量优先原则
        var a=4; 
    }
    fn(); 
    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
        var a=11;
        console.log(a);//11
        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(6);//报错 
    var a={
        a:function(a){
            var a
            console.log(a);
        }
    }
    a.a(5); //5作爲實參代入對象a的a方法中的a參數,打印結果為5
    function fn(f){
        var x=20;
        f(x);
    }
    function fn1(x){
        console.log(x);
    }
    fn(fn1);//打印20,fn1作爲實參傳到fn中對應形參f,fn函數内部的x=20作爲實參傳入f(x),根據fn1打印20

    6.return

    刪除函數 fn=null

    返回局部變量
    返回函數
    返回對象
    返回參數(參數為基本類型或引用類型)
    function fn(a,b){
        a+=b;
        return a;
    }
    ​
    var a=10;
    var b=20;
    fn(a,b);
    console.log(a); 
    ​
    function fn(obj){
        obj.a=10;
        return obj;
    }
    ​
    var obj={
        a:1
    }
    var  obj1=fn(obj);
    console.log(obj===obj1); 

    7.回調&遞歸

    回調:将一个函数以参数的形式传入到另一个函数中,并且在那个函数执行
    根据内存大小设置递归上限的次数,如果递归次数太多,就会堆栈上限溢出,不能超過十億次
    setTimeout:
    console.log("a");
    var id=setTimeout(fn,2000,5);
    function fn(n){
        console.log(n);
        clearTimeout(id);
    }
    console.log("b");
    setInterval:
    var id=setInterval(fn,2000);
    var num=0;
    function fn(){
        console.log("aa");
        num++;
        if(num>3)clearInterval(id);
    }
    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);
    //拿到有id屬性的DOM結構放到一個對象裏
    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);
    //對象的深複製
    function cloneObj(obj,target){
        target=target || {};
        for(var prop in obj){
            if(typeof obj[prop]==="object" && obj[prop]!==null){//排除對象的屬性為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);

    三、區分數組和對象

    var arr=[1,2,3,4];
    console.log(typeof arr);//object不能區分數組與對象
    console.log(arr.constructor===Array);
    console.log(Array.isArray(arr));//ES6
    console.log(String(arr)!=="[object Object]");

     

  • 相关阅读:
    HDU 5791 Two (DP)
    POJ 1088 滑雪 (DPor记忆化搜索)
    LightOJ 1011
    POJ 1787 Charlie's Change (多重背包 带结果组成)
    HDU 5550 Game Rooms (ccpc2015 K)(dp)
    HDU 5542 The Battle of Chibi (ccpc 南阳 C)(DP 树状数组 离散化)
    HDU 5543 Pick The Sticks (01背包)
    HDU 5546 Ancient Go (ccpc2015南阳G)
    NB-IoT的DRX、eDRX、PSM三个模式 (转载,描述的简单易懂)
    MQTT 嵌入式端通讯协议解析(转)
  • 原文地址:https://www.cnblogs.com/ananasfleisch/p/13285376.html
Copyright © 2011-2022 走看看