js对象以及对象深复制

对象:

对象是一种以键值对描述的数据格式

=====》 键值对 key:value

分类描述需要用到键值对的方式

所有东西都是对象

字符,数值,布尔值不是用构造函数创建的会放在栈中,如果使用构造函数创建的字符,数值,布尔值都会被放在堆中。但是归根结底他们的根本部分都是对象(object)

//类 父类 子类 超类 对象

类 :就是类别,是对一些具有相同属性和方法的集合做出的抽象概率,类自身也可以是一个对象(类本身可是虚拟抽象概率,也可以是实体存在的对象)

class Box extends Array{

    a=1;

    static b = 2;

    constructor(){

        super();//执行超类的构造函数

    }

    static plays(){

    }

    play(){

    }

    join(){

        //如果该方法是超类的一个方法时

        super.join();//当需要执行超类的该方法内容时,可以这么写

    }

}

上面是一个抽象类别,描述了一个群体,这个群体中每个对象都有一个a的属性,默认值为1,有一个play方法,只需要通过new这个类就可以创造该类对象

let b = new Box();

let b1 = new Box();

Box相对b,b1这样的对象来说是一个抽象描述

Box变成了对象,其实这里的属性和方法就是对于该种类的属性描述和方法内容,他不是针对实例化的对象产生,而是针对该类别统一描述

Box.b = 10;

Box.plays();

子类 当需要完成一个新的类别时,这个类别是针对某个类别的拓展产生的,这个新的类别就是基于原来类别的新类,也就是我们所说的子类。而原来的而类别相当于拓展出来的新类别来说就是父类

当这种不断拓展产生新的类别时,形成的关系链我们称为原型链

我们将最开始,也就是最底层的父类称为基类,万物的基类就是Object

/子类的父类称为超类,super

对象就是通过实例化类别形成的内容

创建对象 和删除对象

//字面量实例化

var obj = {a:1,b:2};

//构造函数实例化

var obj1 = new Object({a:1,b:2});

//引用地址完全不同

console.log(obj===obj1); //false

//如果需要比对对象的属性和值是否完全相同,可以转换为字符串,然后比对

console.log(JSON.stringify(obj)===JSON.stringify(obj1)); //true

console.log([]===[]);//fasle

console.log([]===true);//false

console.log(![]===false);//true

//以obj对象为原型创建初obj2

//脱离了类别直接以对象继承

var obj2 = object.create(obj);

class Object1{

    a:1;

    b:2;

    constructor(){

    };

}

class Object2 extend Object1{

}

var obj2 = new Object2();

console.log(obj2);

//__proto__原型链

obj.a = 10;//如果原型链对应的对象发生修改,该对象的原型链也会发生改变

obj2.c = 10;

var obj3 = Object.create(obj2);

//当获取对象属性时,如果欸有该对象属性,则查找离其最近的原型链上的该属性,如果有则返回该值

console.log(obj3);

//设置对象属性时,只能设置该对象的对象属性,不能修改对象的原型属性,

//设置一个对象属性时,先查看是否有该对象属性,如果没有则创建一个属性,赋值,如果有了该对象,则修改该对象

//ES5允许直接操作原型链的属性值,但是我们限制只能获取其值,不要修改值

obj3.proto.proto.b=0;//不建议使用原型链修改值

console.log(obj3);

//删除属性和方法

delete obj2.b;//删除对象的对象属性

delete obj2.__proto__.b;//删除原型链属性

obj = null;

obj2.__proto__=obj2.__proto__.__proto__;

console.log(obj2);

Object.assign();

//Object.assign(目标对象,源对象1,源对象2,....);//这个方法返回目标对象

var obj1 = {};

Object.assign(obj1,obj);

console.log(obj1);

var obj1 = Object.assign({},obj);

var obj1 = {c:3};

Object.assign(obj1,obj)

console.log(obj1);

var obj2= {....obj};//目标对象的内容会被覆盖

//如果多源对象赋值,有相同的属性,后面的源对象属性值会覆盖前面的源对象的属性值

var obj2 = Object.assign({},obj,obj1);

console.log(ob2);

Object.assign是浅复制,仅去除了对象的第一层的引用关系,而第二层过着更深的引用关系仍然存在

1.转存失败

2.重新上传

3.取消

//只能赋值对象的可以枚举属性

对象属性定义

var obj = {};

obj.a = 10;

obj["b"]=20;

//对象属性的描述对象(描述属性)

Object.defineProperty(obj,"a",{

    //描述a的属性

    value:10,

    configurable:true,//是否可以删除,以及是否可以修改的描述对象

    enumerable:true,//是否可以枚举

    writable:true,//是否可以修改

});

Object.defineProperty(obj,"a",{

    //描述a的属性

    configurable:true,//是否可以删除,以及是否可以修改的描述对象

    enumerable:true,//是否可以枚举

    //

    set:function(value){

        this._a=value;

    }

    //

    get:function(){

        return this._a;

    }

});

//定义多个属性

var obj = {};

Object.defineProperties(obj,{

    a:{

        value : 1,

    },

    b:{

        writable:true,

        enumerable:true,

        value:2

    },

    c:{

        congigurable:true,

        writable:true,

        value:3

    },

    d:{

        enumerable:true;

        set:functio(value){

            this._d=value

        }

        get:function(){

            return this._d;

        }

    }

});

//获取对象属性名的数组

var arr = Object.getOwnPropertyName(obj);

console.log(arr);

//获取对象属性的描述对象

var desc = Object.getOwnPropertyName(obj,"a");

对象深复制

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Document</title>

</head>

<body>

    <div class="div1"></div>

    <div class="div1"></div>

    <div class="div1"></div>

    <script>

        var obj1={};

        Object.defineProperties(obj1,{

            a:{

                value:1

            },

            b:{

                writable:true,

                enumerable:true,

                value:2

            },

            c:{

                configurable:true,

                writable:true,

                value:3

            },

            d:{

                enumerable:true,

                set:function(value){

                    this._d=value;

                },

                get:function(){

                    if(!this._d) this._d=0;

                    return this._d;

                }

            }

        });

        var obj={

            a:1,

            b:[1,2,3],

            c:{

                a:"a",

                b:true,

                c:{

                    a:new Date(),

                    b:/^[a-z](!=[0-9])$/i,

                    c:{

                        a:new XMLHttpRequest(),

                        b:[

                            [1,2,3,4,5],

                            [2,3,4,5,6],

                            [3,4,5,6,7]

                        ],

                        c:{

                            a:[

                                {a:1,b:2},

                                {a:2,b:3},

                                {a:3,b:4}

                            ],

                            b:function(){

                                console.log("aaa");

                            },

                            c:obj1,

                            d:document.querySelector(".div1")

                        }

                    }

                }

            }

        }

        var obj2=cloneObject({},obj);

        // obj.c.c.c.b[0][0]=0;

        // Object.defineProperty(obj.c.c.c.c.c,"c",{

        //    enumerable:true,

        //    configurable:true,

        //    value:3,

        //    writable:true

        // })

        console.log(obj,obj2);

        // console.log(Object.getOwnPropertyNames(document.querySelector("div")));

        function cloneObject(target,source){

            var names=Object.getOwnPropertyNames(source);

            for(var i=0;i<names.length;i++){

                var desc=Object.getOwnPropertyDescriptor(source,names[i]);

                if(typeof desc.value==="object" && desc.value!==null){

                    var objs;

                    if(desc.value.constructor===Date){

                        objs=new desc.value.constructor(desc.value);

                    }else if(desc.value.constructor===RegExp){

                        objs=new desc.value.constructor(desc.value.source,desc.value.flags);

                    }else if(desc.value.__proto__.__proto__ && desc.value.__proto__.__proto__.constructor===HTMLElement){

                        objs=document.createElement(desc.value.nodeName);

                    }else{

                        objs=new desc.value.constructor();

                    }

                    Object.defineProperty(target,names[i],{

                        configurable:desc.configurable,

                        writable:desc.writable,

                      enumerable:desc.enumerable,

                        value:objs

                    });

                    cloneObject(objs,desc.value);

                }else{

                    Object.defineProperty(target,names[i],desc);

                }

            }

            return target;

        }

    </script>

</body>

</html>

setter和getter访问器属性

//ES6以后才能用set和get

//当创建对象时,可以直接使用set和get访问器属性

var obj = {

        _num = 1;

        set num(){

            this._num = value;

        },

        get num(){

            return this._num;

        }

    }

console.log(obj);

//在已有得对象中添加set和get访问器属性

var obj = {};

//不能和writable,value连用,置样使用setter和getter不能使用writable,value

Object.defineProterty(obj,"num",{

    set:function(value){

        this._num = value;

    },

    get:function(){

        if(!this._num) this._num=1;

        return this._num;

    }

})

//ES6类中设置setter和getter访问器

class  Box{

    constructor(){

    }

    set num(value){

        this._num = value;

    }

    get num(){

        if(!this._num) this._num=1;

        return this._num;

    }

    static set nums(value){

        Box._num = value;

    }

    static get nums(){

        if(!Box.num) Box.nums = 0;

        return Box.nums;

    }

}

let b = new Box();

console.log(b,Box);

console.dir(Box);

set和get到底是干啥用的?

var div = document.createElement("div");

div.style.backgroundColor = "red";

document.body.appendChild(div);

Object.defineProterty(div,"w",{

    enumerable:true;

    //set函数得参数有且只有一个,这个参数就是设置属性等于值时,这个设置得值

    set:function(value){

        console.log(value);

        if(typeof value === "number") value+="px";

        this.style.width = value;

    }

    get:function(){

    }

})

Object.defineProterty(div,{

    w:{

          enumerable:true;

            //set函数得参数有且只有一个,这个参数就是设置属性等于值时,这个设置得值

          set:function(value){

            console.log(value);

            if(typeof value === "number") value+="px";

            this.style.width = value;

            }

            get:function(){

                if(!this._w) this._w = 0;

                return this._w;

            }

      }

    h:{

          enumerable:true;

            //set函数得参数有且只有一个,这个参数就是设置属性等于值时,这个设置得值

          set:function(value){

            console.log(value);

            if(typeof value === "number") value+="px";

            this.style.height = value;

            }

            get:function(){

                if(!this._h) this._h = 0;

                return this._h;

            }

      }

})

//所有属性后面有等号,就意味设置该属性,也就会调用set方法

    div.w = 1;

    div.h = 1;

    setInterval(function(){

    div.w++;

    div.h++;

},16)

//所有属性后面没有等号,就意味调用该属性,也就会调用get方法

//一旦使用set get 这种访问属性,该属性不具备属性的存储功能

console.log(div.w);

setter getter 访问器属性

//如果对象中只有一个set,没有get,就说明该属性是只写属性

//如果对象中只有一个get,没有set,就说明该属性是只读属性

var obj = {

        _a = 10;

        get a(){

            return this._a;

        }

    }

class Box{

    a= 1;

    static a = 1;

        consturctor(){

    }

    //可以利用get方法来设置只读属性

    static get 

}

数据结构

数组:所谓数组,是无序的元素序列。若将有限个类型相同的变量名的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称数组元素,有时也称为下标变量。用于区分数组的各个元素的数字编号为下标。数组是在程序设计中,为了处理方便,把具有相同的若干元素按无序的形式组织起来的一种形式。这些无序排列的同类数据元素的集合称为数组。

var arr = [1,2,3,4];

//2 数组元素

//arr[0]—> 0是元素下标

//将无序数据有序的组合

//当数据不需要考虑是针对什么名字,仅仅是以列表的形式出现,以便于循环遍历以及排序,筛选等操作使用

//数组的元素顺序发生变化后,就不能够确定值是针对什么内容,这样也会操作数组的元素无法一一对应使用

//只有使用键值对的形式才会解决一一对应问题

//在数组中元素直接是依靠下标的顺序排列,如果其中删除了一个元素,后面的元素就会向前补位,这样就会造成效率的低下,如果删除数组最前面的元素,它的效率最为低下。

//在有时候不需要重复元素,数组无法判断,形成冗余数组

//数组元素是紧密元素

//let a = new Set();//不重复的值

//集和:键值对(key:value)的形式存在,如果出现集合嵌套问题就叫做多重集合

//object,dictionary

//所有对象的运算都是松散排列

//因为对象是松散集合,因此添加元素,插入元素,删除元素,查找元素,都和其他元素都没有关系

//缺陷:

//元素之间没有关系,因此对象无法针对下一个兄弟关系元素进行操作,也不能统计出整个对象的长度

//在很多语言中使用for…in遍历时,每次遍历的顺序都是随机的(js十个特殊例外,遍历顺序是根据key创建的先后)

let obj = {

a:1,b : 2

1

}

console.log(on.b);

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355