學習筆記——對象方法整理

在前面寫過兩篇文章,分別是關於數組和字符串的方法解析,那這三劍客之一的對象怎麼能不寫呢,本次來整理一下對象有哪些經常使用的方法,下面介紹的每一個方法都會寫與示例,方便你們對照查看。^_^面試

對象是指: 成對的名稱(字符串)與值(任何值),其中名稱經過冒號與值分隔;segmentfault

1、建立對象的方式,如下列出了四種,可根據實際狀況來選擇

(1)字面量形式(最經常使用),在實際中運用較多,較方便,易上手:數組

let object={
    a:1,
    b:2
};
console.log(object);       //{a:1,b:2}
複製代碼

(2)對象實例(傳統的形式,在操做對象時用的較頻繁。):bash

let object=new Object();
    object.a=1;
    object.b=2;
console.log(object);        //{a:1,b:2}
複製代碼

(3)構造函數形式:微信

function employee(name,job,born) {
    this.name=name;
    this.job=job;
    this.born=born;
}
let bill=new employee("Bill Gates","Engineer",1985);
 
// employee {name: "Bill Gates", job: "Engineer", born: 1985} 
複製代碼

(4)工廠模式:函數

工廠模式的優點是可以一次性出廠多個相同的屬性的對象,節省資源佔用,缺點是:屬性都爲相同的,若是要建立不一樣的須要從新生成。工具

function create(name,job,born){
    let people=new Object();
    people.name=name;
    people.job=job;
    people.born=born;
    people.show=function(){
    console.log("name:"+this.name+","+"job:"+this.job+","+"born:"+this.born)
    };
    return people;
}
let friend=create("Christine","teacher","1990");
 
friend.show();  //name:Christine,job:teacher,born:1990
複製代碼

(5)原型模式post

將屬性賦值到對象的原型上,並不會影響其自己的屬性。測試

function create(name,job,born){};
    create.prototype.name="Christine";
    create.prototype.job="teacher";
    create.prototype.born="1990";
    create.prototype.show=function(){
    console.log("name:"+this.name+","+"job:"+this.job+","+"born:"+this.born)
};
let friend=new create();
friend.show();   //name:Christine,job:teacher,born:1990
複製代碼

(6)ES6 class模式ui

//定義類
    class Point {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            };
            //定義方法
            toString() {
                return '(' + this.x + ', ' + this.y + ')';
            }
            multiplication() {
                return this.x * this.y
            }
            test() {
                return '1231354654'
            }
        }
        console.log(Point.name)  
        //Point (name屬性老是返回緊跟在class關鍵字後面的類名。)
        
        // 實例化並調用(實例化和調用方法同es5相同)
        let x = new Point(5, 6)
        console.log(x.toString(), '相乘結果:' + x.multiplication(), x.test())
        // (5, 6) 相乘結果:30 1231354654
       
        // 快速添加方法到原型上 (以下圖,直接可添加到原型)
        Object.assign(Point.prototype, {
            dosomething() { },
            toValue() { }
        });
        console.log(Point.prototype)
複製代碼

2.Object.assign()淺拷貝 && JSON.parse(JSON.stringify())深拷貝

拷貝:其實就是一個對象複製給另一整個對象,讓對象相互不影響。對象的拷貝又分爲淺拷貝和深拷貝:對象的淺拷貝(只拷貝一層);對象的深拷貝(拷貝多層);

!注意:淺拷貝和深拷貝只針對object和Array這樣的複雜的對象

Object.assign()方法用於將全部可枚舉屬性的值從一個或多個源對象複製到目標對象,它將返回目標對象。 Object.assign(target, ...sources)

參數:

target:目標對象;sources:源對象;返回值:目標對象。

例:

(1)用來複制一個新對象,並不會影響原對象

let obj = { a: 1 };
let copy = Object.assign({}, obj);
console.log(copy);    // { a: 1 }
複製代碼

(2)用來合併對象屬性,將源對象的全部可枚舉屬性,複製到目標對象。

//object.assign(obj, obj2)  obj2是源對象,obj 是目標對象,返回目標對象
 
let obj = { a: 1 };
let obj2={b:2};

console.log(Object.assign(obj,obj2)===obj);  //true,返回目標對象
console.log(obj);       //{a:1,b:2} obj的值已被更改
複製代碼

(3)若是目標對象和源對象中有相同的鍵,則屬性將被源對象的屬性覆蓋,後面的源屬性會覆蓋以前的相同鍵的源屬性。

let obj = { a: 1 };
let obj2 = {a:5,b:2};
let obj3 = {b:1,d:0};
Object.assign(obj,obj2,obj3);

console.log(obj);       // {a: 5, b: 1, d: 0}
複製代碼

obj和obj2同時擁有相同的鍵a,但兩個值不一樣,obj是目標對象,因此會被源對象obj2的值覆蓋,obj2obj3也同時擁有相同的鍵b,在拷貝時,obj3排在obj2的後面,因此obj2被覆蓋 ,最終打印結果是:{a:5,b:1,d:0}

(4)當assign只有一個對象時,則直接返回這個對象,不作任何操做;

let obj = { a: 1 }
Object.assign(obj);
console.log(obj);        //{a:1}
複製代碼

(5)Object.assign()方法實行的是淺拷貝,而不是深拷貝。也就是說,若是源對象某個屬性的值是對象,那麼目標對象拷貝獲得的是這個對象的引用。

let obj1 = { a: 0 , b: { c: 0}};
let obj2 = Object.assign({}, obj1);
obj1.b.c=5;

console.log(obj2)       //{a:0,b:{c:5}};
複製代碼

當咱們在改變obj1的值時,並無想改變obj2,但obj2的值也發生了改變,這違背了咱們的想法。

(6)給當前的對象添加新的屬性

對象儘可能靜態化,一旦定義,就不得隨意添加新的屬性。若是添加屬性不可避免,要使用Object.assign方法。

const a = {};
Object.assign(a, { x: 3 });  // a => x:3
複製代碼

若是添加相同的屬性,舊屬性的值會被新的值覆蓋:

const a = { x: 5 };
Object.assign(a, { x: 3 });  // a => x:3
複製代碼

(7)JSON.parse(JSON.stringify())實現深拷貝

let obj1 = { a: 0 , b: { c: 0}};
let obj3 = JSON.parse(JSON.stringify(obj1));
obj1.a = 4;
obj1.b.c = 4;
console.log(obj3);     //{ a: 0 , b: { c: 0}};
複製代碼

上述方法,大部分狀況是能夠解決,但有如下幾種狀況沒法識別:

  1. 會忽略 undefined
  2. 會忽略 symbol
  3. 不能序列化函數
  4. 不能解決循環引用的對象

針對這幾個問題,也不是沒有解決方法,能夠本身去實現一個深拷貝,但須要考慮各類類型以及邊界值,我更推薦使用 lodash工具庫的深拷貝函數cloneDeep()

3、Object.entries()

返回一個數組,其元素是與直接在object上找到的可枚舉屬性鍵值對相對應的數組。屬性的順序與經過手動循環對象的屬性值所給出的順序相同。

例: (1).當鍵值爲正常字符時,返回的鍵的值爲字符串

let obj1 = {a:1,b:2};
let obj2 = Object.entries(obj1);
console.log(obj2) ;       //  [ ["a":1],["b":2] ] 
複製代碼

(2)當鍵值爲數字時,返回的鍵的值也是字符串

let obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj));     // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ] 
複製代碼

(3)當鍵值的數字錯亂無序時,它會將其排序後返回

let anObj = { 100: 'a', 2: 'b', 9: 'c' };
console.log(Object.entries(anObj));   //[["2","b"],["9","c"],["100","a"]]
複製代碼

(4)展開對象

const object1 = {
 a: 'somestring',
 b: 42
};

for (let [key, value] of Object.entries(object1)) {
 console.log(`${key}: ${value}`);
}
//     "a: somestring"
//     "b: 42"
複製代碼

4、Object.is()方法判斷兩個值是不是相等的值

Object.is(value1, value2);

參數:

value1:須要比較的第一個值。 value2:須要比較的第二個值。 返回值:表示兩個參數是否相同的Boolean

(1)比較字符串

比較字符串(單純的比較字符串的每一位,若是徹底相同返回true,只要有一個不同,返回false)

Object.is('foo', 'foo’); //true; Object.is('fo', 'foo’);           //false
複製代碼

(2)比較數組

比較數組 (對數組無感,即便是相同的數組,或者是相同的空數組,都返回false)

Object.is([11,12],[11,12]).        //false
 
Object.is([],[])                   //false 
複製代碼

(3)比較window

Object.is(window, window)           //true
 
Object.is(window, document);       //false
複製代碼

(4)比較特殊對象undifined 和null

undefinednull都等於它自己,但undefined不等於null

Object.is(null, null);              //true

Object.is(undefined,undefined);     //true
 
Object.is(undefined,null);          //false 
複製代碼

(5)比較正常對象

let test={a:1,b:2};     

let test1={a:2,b:5};
 
Object.is(test,test1)            //false
----------------------------------------------------------
let test={a:1,b:2};              //比較的兩端需爲同樣的元素,當一邊爲變量時,另外一邊也必須是變量
 
Object.is(test,{a:1,b:2}).       //false
 
Object.is(test,test).            //true複製代碼

五.Object.keys()

Object.keys()方法返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組的屬性的排列順序和使用for..in循環遍歷該對象時返回的順序一致二者的主要區別是 一個 for-in循環還會枚舉其原型鏈上的屬性

Object.keys(obj)

參數

obj:要返回其枚舉自身屬性的對象。

返回值:一個表示給定對象的全部可枚舉屬性的字符串數組。

描述:Object.keys返回一個全部元素爲字符串的數組,其元素來自於從給定的對象上面可直接枚舉的屬性。這些屬性的順序與手動遍歷該對象屬性時的一致。

(1)數組Array對象(返回索引值)

let arr=[1,2,3];            
Object.keys(arr)         //  ["0", "1", "2」] 複製代碼

(2)object對象(返回key值)

let obj = { foo: "bar", baz: 42 };
Object.keys(obj)        //  ["foo", "baz」] 複製代碼

(3)類數組,對象

let obj = { 0 : "a", 1 : "b", 2 : "c」}; Object.keys(obj) // ["0", "1", "2"] 複製代碼

(4)類數組對象 隨機key排序

let Obj = { 100: 'a’, 2: 'b’,7: 'c’ }; console.log(Object.keys(Obj)); // ['2', '7', '100’]. 返回從小到大排序後的結果
複製代碼

六.obj.hasOwnProperty(key) 檢測對象有沒有指定的key

hasOwnProperty()方法會返回一個布爾值,指示對象是否具備指定的屬性做爲自身(不繼承)屬性。 obj.hasOwnProperty(prop)

參數

prop:要檢測的屬性 字符串 名稱或者 Symbol

返回值:用來判斷某個對象是否含有指定的屬性的 Boolean

全部繼承了 Object 的對象都會繼承到 hasOwnProperty 方法。這個方法能夠用來檢測一個對象是否含有特定的自身屬性;和 in 運算符不一樣,該方法會忽略掉那些從原型鏈上繼承到的屬性。

let obj=new Object();
    obj.a=5;
    
console.log(obj.hasOwnProperty('a’)) // true delete obj.a; console.log(obj.hasOwnProperty(‘a’)). //false 複製代碼

7、Object.values()

方法返回一個給定對象本身的全部可枚舉屬性值的數組,值的順序與使用for..in循環相同,返回的對象的value值,與Object.key()相反

例: (1)正常對象

let obj={a:1,b:2,c:3};
console.log(Object.values(obj))         //  [1, 2, 3]
複製代碼

(2)類數組對象

let obj ={0:'a',1:'b',2:'c'};
console.log(Object.values(obj)).       //  a,b,c
複製代碼

(3) key值爲無序number

let obj={100:'a',10:'b',1:'1'};
console.log(Object.values(obj)).   // ["1", "b", "a"]
複製代碼

8、...擴展運算符

對象的擴展運算符(...)用於取出參數對象的全部可遍歷屬性,拷貝到當前對象之中。

let z = { a: 3, b: 4 };
let n = { ...z };     //  n =>  { a: 3, b: 4 }
複製代碼

因爲數組是特殊的對象,因此對象的擴展運算符也能夠用於數組。

let foo = { ...['a', 'b', 'c'] };  //  foo=> {0: "a", 1: "b", 2: "c"}foo

複製代碼

對象的擴展運算符等同於使用Object.assign()方法。可複製對象

let aClone = { ...a };
// 等同於
let aClone = Object.assign({}, a);

-------

let z = { a: 3, b: 4 };
let n = { ...z };  // n => {a: 3, b: 4}
n.a=8
console.log(z)  // {a: 3, b: 4}

複製代碼

9、Object.defineProperty的做用

今天有看了一篇面試的文章,其中有一題就問到Object.defineProperty的做用,說實話,若是問我,我也答不上來,隨即百度找到了解析,而後就順便添加到這次筆記中,以便之後查看。

語法: Object.defineProperty(obj, prop, descriptor)

參數說明:

obj:必需。目標對象 
prop:必需。需定義或修改的屬性的名字
descriptor:必需。目標屬性所擁有的特性
複製代碼

針對對象到屬性,咱們能夠給這個屬性設置一些特性,屬性的值是否能夠被重寫?好比是否只讀?;是否能夠被for..inObject.keys()遍歷,是否能夠刪除目標屬性或是否能夠再次修改屬性的特性?

帶着上面的問題,咱們來看看Object.defineProperty能給咱們帶來哪些神奇的效果(數據描述中的屬性都是可選的)!

1. value :屬性對應的值,可使任意類型的值,默認爲undefined

let obj = {}
//第一種狀況:不設置value屬性
Object.defineProperty(obj,"newKey",{

});
console.log( obj.newKey );  //undefined

------------------------------

//第二種狀況:設置value屬性
Object.defineProperty(obj,"newKey",{
    value:"hello"
});
console.log( obj.newKey );  //hello
複製代碼

2. writable :屬性的值是否能夠被重寫(默認爲false)。設置爲true能夠被重寫;設置爲false,不能被重寫。

let obj = {}
//第一種狀況:writable設置爲false,不能重寫。
Object.defineProperty(obj,"newKey",{
    value:"hello",
    writable:false
});

//更改newKey的值
obj.newKey = "change value";
console.log( obj.newKey );  //hello
------------------------------------
//第二種狀況:writable設置爲true,能夠重寫
Object.defineProperty(obj,"newKey",{
    value:"hello",
    writable:true
});

//更改newKey的值
obj.newKey = "change value";
console.log( obj.newKey );  //change value
複製代碼

3. enumerable :此屬性是否能夠被枚舉(使用for...in或Object.keys())。設置爲true能夠被枚舉;設置爲false,不能被枚舉。(默認爲false)。

var obj = {}
//第一種狀況:enumerable設置爲false,不能被枚舉。
Object.defineProperty(obj,"newKey",{
    value:"hello",
    writable:false,
    enumerable:false
});

//枚舉對象的屬性
for( var attr in obj ){
    console.log( attr );  
}
//第二種狀況:enumerable設置爲true,能夠被枚舉。
Object.defineProperty(obj,"newKey",{
    value:"hello",
    writable:false,
    enumerable:true
});

//枚舉對象的屬性
for( var attr in obj ){
    console.log( attr );  //newKey
}
複製代碼

4.configurable :是否能夠刪除目標屬性或是否能夠再次修改屬性的特性(writable, configurable, enumerable)。設置爲true能夠被刪除或能夠從新設置特性;設置爲false,不能被能夠被刪除或不能夠從新設置特性。默認爲false

這個屬性起到兩個做用:

目標屬性是否可使用delete刪除
    
    目標屬性是否能夠再次設置特性
複製代碼
//-----------------測試目標屬性是否能被刪除------------------------
var obj = {}
//第一種狀況:configurable設置爲false,不能被刪除。
Object.defineProperty(obj,"newKey",{
    value:"hello",
    writable:false,
    enumerable:false,
    configurable:false
});
//刪除屬性
delete obj.newKey;
console.log( obj.newKey ); //hello

//第二種狀況:configurable設置爲true,能夠被刪除。
Object.defineProperty(obj,"newKey",{
    value:"hello",
    writable:false,
    enumerable:false,
    configurable:true
});
//刪除屬性
delete obj.newKey;
console.log( obj.newKey ); //undefined

//-----------------測試是否能夠再次修改屬性/特性------------------------
var obj = {}
//第一種狀況:configurable設置爲false,不能再次修改屬性/特性。
Object.defineProperty(obj,"newKey",{
    value:"hello",
    writable:false,
    enumerable:false,
    configurable:false
});

//從新修改屬性/特性
Object.defineProperty(obj,"newKey",{
    value:"hello",
    writable:true,
    enumerable:true,
    configurable:true
});
console.log( obj.newKey ); //報錯:Uncaught TypeError: Cannot redefine property: newKey

//第二種狀況:configurable設置爲true,能夠再次修改屬性/特性。
Object.defineProperty(obj,"newKey",{
    value:"hello",
    writable:false,
    enumerable:false,
    configurable:true
});

//從新修改屬性/特性
Object.defineProperty(obj,"newKey",{
    value:"hello",
    writable:true,
    enumerable:true,
    configurable:true
});
console.log( obj.newKey ); //hello
複製代碼

除了能夠給新定義的屬性設置屬性/特性,也能夠給已有的屬性設置屬性/特性.

//定義對象的時候添加的屬性,是可刪除、可重寫、可枚舉的。
var obj = {
    test:"hello"
}

//改寫值
obj.test = 'change value';

console.log( obj.test ); //'change value'

Object.defineProperty(obj,"test",{
    writable:false
})


//再次改寫值
obj.test = 'change value again';

console.log( obj.test ); //依然是:'change value'
複製代碼

提示:一旦使用Object.defineProperty給對象添加屬性,那麼若是不設置屬性的特性,那麼configurableenumerablewritable這些值都爲默認的false

var obj = {};
//定義的新屬性後,這個屬性的特性中configurable,enumerable,writable都爲默認的值false
//這就致使了neykey這個是不能重寫、不能枚舉、不能再次設置特性
//
Object.defineProperty(obj,'newKey',{

});

//設置值
obj.newKey = 'hello';
console.log(obj.newKey);  //undefined

//枚舉
for( var attr in obj ){
    console.log(attr);
}
複製代碼

參考資料:傳送門


做者:晴天de雨滴    
    出處:https://juejin.im/post/5a125827518825293b4fea8a
    版權全部,歡迎保留原文連接進行轉載:) 
複製代碼

若是你對我對文章感興趣或者有些建議想說給我聽👂,也能夠添加一下微信哦!

若是親感受個人文章還不錯的話,能夠一下添加關注哦!

gold-cdn.xitu.io/2017/11/19/15fd4be41482278c?w=1000&h=800&f=png&s=204515)

最後:
        祝各位工做順利!
                        -小菜鳥Christine
複製代碼
相關文章
相關標籤/搜索