對象:
對象是一種以鍵值對描述的數(shù)據(jù)格式
=====》 鍵值對 key:value
分類描述需要用到鍵值對的方式
所有東西都是對象
字符,數(shù)值桦锄,布爾值不是用構(gòu)造函數(shù)創(chuàng)建的會放在棧中,如果使用構(gòu)造函數(shù)創(chuàng)建的字符宣蠕,數(shù)值脐区,布爾值都會被放在堆中。但是歸根結(jié)底他們的根本部分都是對象(object)
//類 父類 子類 超類 對象
類 :就是類別荣堰,是對一些具有相同屬性和方法的集合做出的抽象概率,類自身也可以是一個對象(類本身可是虛擬抽象概率竭翠,也可以是實體存在的對象)
class Box extends Array{
? ? a=1;
? ? static b = 2;
? ? constructor(){
? ? ? ? super();//執(zhí)行超類的構(gòu)造函數(shù)
? ? }
? ? static plays(){
? ? }
? ? play(){
? ? }
? ? join(){
? ? ? ? //如果該方法是超類的一個方法時
? ? ? ? super.join();//當(dāng)需要執(zhí)行超類的該方法內(nèi)容時振坚,可以這么寫
? ? }
}
上面是一個抽象類別,描述了一個群體斋扰,這個群體中每個對象都有一個a的屬性渡八,默認(rèn)值為1,有一個play方法传货,只需要通過new這個類就可以創(chuàng)造該類對象
let b = new Box();
let b1 = new Box();
Box相對b屎鳍,b1這樣的對象來說是一個抽象描述
Box變成了對象,其實這里的屬性和方法就是對于該種類的屬性描述和方法內(nèi)容问裕,他不是針對實例化的對象產(chǎn)生逮壁,而是針對該類別統(tǒng)一描述
Box.b = 10;
Box.plays();
子類 當(dāng)需要完成一個新的類別時,這個類別是針對某個類別的拓展產(chǎn)生的僻澎,這個新的類別就是基于原來類別的新類貌踏,也就是我們所說的子類十饥。而原來的而類別相當(dāng)于拓展出來的新類別來說就是父類
當(dāng)這種不斷拓展產(chǎn)生新的類別時窟勃,形成的關(guān)系鏈我們稱為原型鏈
我們將最開始,也就是最底層的父類稱為基類逗堵,萬物的基類就是Object
/子類的父類稱為超類秉氧,super
對象就是通過實例化類別形成的內(nèi)容
創(chuàng)建對象 和刪除對象
//字面量實例化
var obj = {a:1,b:2};
//構(gòu)造函數(shù)實例化
var obj1 = new Object({a:1,b:2});
//引用地址完全不同
console.log(obj===obj1); //false
//如果需要比對對象的屬性和值是否完全相同,可以轉(zhuǎn)換為字符串蜒秤,然后比對
console.log(JSON.stringify(obj)===JSON.stringify(obj1)); //true
console.log([]===[]);//fasle
console.log([]===true);//false
console.log(![]===false);//true
//以obj對象為原型創(chuàng)建初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;//如果原型鏈對應(yīng)的對象發(fā)生修改汁咏,該對象的原型鏈也會發(fā)生改變
obj2.c = 10;
var obj3 = Object.create(obj2);
//當(dāng)獲取對象屬性時,如果欸有該對象屬性作媚,則查找離其最近的原型鏈上的該屬性攘滩,如果有則返回該值
console.log(obj3);
//設(shè)置對象屬性時,只能設(shè)置該對象的對象屬性纸泡,不能修改對象的原型屬性漂问,
//設(shè)置一個對象屬性時,先查看是否有該對象屬性,如果沒有則創(chuàng)建一個屬性蚤假,賦值栏饮,如果有了該對象,則修改該對象
//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(目標(biāo)對象,源對象1灶平,源對象2伺通,....);//這個方法返回目標(biāo)對象
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};//目標(biāo)對象的內(nèi)容會被覆蓋
//如果多源對象賦值逢享,有相同的屬性泵殴,后面的源對象屬性值會覆蓋前面的源對象的屬性值
var obj2 = Object.assign({},obj,obj1);
console.log(ob2);
Object.assign是淺復(fù)制,僅去除了對象的第一層的引用關(guān)系拼苍,而第二層過著更深的引用關(guān)系仍然存在
1.轉(zhuǎn)存失敗
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;
? ? ? ? }
? ? }
});
//獲取對象屬性名的數(shù)組
var arr = Object.getOwnPropertyName(obj);
console.log(arr);
//獲取對象屬性的描述對象
var desc = Object.getOwnPropertyName(obj,"a");
對象深復(fù)制
<!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
//當(dāng)創(chuàng)建對象時疮鲫,可以直接使用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類中設(shè)置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函數(shù)得參數(shù)有且只有一個俊犯,這個參數(shù)就是設(shè)置屬性等于值時妇多,這個設(shè)置得值
? ? 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函數(shù)得參數(shù)有且只有一個,這個參數(shù)就是設(shè)置屬性等于值時燕侠,這個設(shè)置得值
? ? ? ? ? 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函數(shù)得參數(shù)有且只有一個者祖,這個參數(shù)就是設(shè)置屬性等于值時,這個設(shè)置得值
? ? ? ? ? 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;
? ? ? ? ? ? }
? ? ? }
})
//所有屬性后面有等號绢彤,就意味設(shè)置該屬性七问,也就會調(diào)用set方法
? ? div.w = 1;
? ? div.h = 1;
? ? setInterval(function(){
? ? div.w++;
? ? div.h++;
},16)
//所有屬性后面沒有等號,就意味調(diào)用該屬性茫舶,也就會調(diào)用get方法
//一旦使用set get 這種訪問屬性械巡,該屬性不具備屬性的存儲功能
console.log(div.w);
setter getter 訪問器屬性
//如果對象中只有一個set,沒有g(shù)et饶氏,就說明該屬性是只寫屬性
//如果對象中只有一個get讥耗,沒有set,就說明該屬性是只讀屬性
var obj = {
? ? ? ? _a = 10;
? ? ? ? get a(){
? ? ? ? ? ? return this._a;
? ? ? ? }
? ? }
class Box{
? ? a= 1;
? ? static a = 1;
? ? ? ? consturctor(){
? ? }
? ? //可以利用get方法來設(shè)置只讀屬性
? ? static get?
}
數(shù)據(jù)結(jié)構(gòu)
數(shù)組:所謂數(shù)組疹启,是無序的元素序列古程。若將有限個類型相同的變量名的集合命名,那么這個名稱為數(shù)組名喊崖。組成數(shù)組的各個變量稱為數(shù)組的分量挣磨,也稱數(shù)組元素菲宴,有時也稱為下標(biāo)變量。用于區(qū)分?jǐn)?shù)組的各個元素的數(shù)字編號為下標(biāo)趋急。數(shù)組是在程序設(shè)計中喝峦,為了處理方便,把具有相同的若干元素按無序的形式組織起來的一種形式呜达。這些無序排列的同類數(shù)據(jù)元素的集合稱為數(shù)組谣蠢。
var arr = [1,2,3,4];
//2 數(shù)組元素
//arr[0]—> 0是元素下標(biāo)
//將無序數(shù)據(jù)有序的組合
//當(dāng)數(shù)據(jù)不需要考慮是針對什么名字,僅僅是以列表的形式出現(xiàn)查近,以便于循環(huán)遍歷以及排序眉踱,篩選等操作使用
//數(shù)組的元素順序發(fā)生變化后,就不能夠確定值是針對什么內(nèi)容霜威,這樣也會操作數(shù)組的元素?zé)o法一一對應(yīng)使用
//只有使用鍵值對的形式才會解決一一對應(yīng)問題
//在數(shù)組中元素直接是依靠下標(biāo)的順序排列谈喳,如果其中刪除了一個元素,后面的元素就會向前補位戈泼,這樣就會造成效率的低下婿禽,如果刪除數(shù)組最前面的元素,它的效率最為低下大猛。
//在有時候不需要重復(fù)元素扭倾,數(shù)組無法判斷,形成冗余數(shù)組
//數(shù)組元素是緊密元素
//let a = new Set();//不重復(fù)的值
//集和:鍵值對(key:value)的形式存在挽绩,如果出現(xiàn)集合嵌套問題就叫做多重集合
//object膛壹,dictionary
//所有對象的運算都是松散排列
//因為對象是松散集合,因此添加元素唉堪,插入元素模聋,刪除元素,查找元素唠亚,都和其他元素都沒有關(guān)系
//缺陷:
//元素之間沒有關(guān)系,因此對象無法針對下一個兄弟關(guān)系元素進(jìn)行操作链方,也不能統(tǒng)計出整個對象的長度
//在很多語言中使用for…in遍歷時,每次遍歷的順序都是隨機的(js十個特殊例外趾撵,遍歷順序是根據(jù)key創(chuàng)建的先后)
let obj = {
a:1,b : 2
1
}
console.log(on.b);