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]");

     

  • 相关阅读:
    所有选择器
    display:block、display:inline与displayinline:block的概念和区别
    jQuery 选择器
    JS日历制作获取时间
    HTML DOM 事件
    访问HTML元素(节点)
    HTML常用标签
    flask+mysql的Docker 部署
    docker(三)
    flask如何部署
  • 原文地址:https://www.cnblogs.com/ananasfleisch/p/13285376.html
Copyright © 2011-2022 走看看