學習筆記——物件方法整理

Christine發表於2018-04-02

在前面寫過兩篇文章,分別是關於陣列和字串的方法解析,那這三劍客之一的物件怎麼能不寫呢,本次來整理一下物件有哪些常用的方法,下面介紹的每個方法都會寫與示例,方便大家對照檢視。^_^

物件是指: 成對的名稱(字串)與值(任何值),其中名稱通過冒號與值分隔;

一、建立物件的方式,以下列出了四種,可根據實際情況來選擇

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

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

(2)物件例項(傳統的形式,在操作物件時用的較頻繁。):

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)原型模式

將屬性賦值到物件的原型上,並不會影響其本身的屬性。

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模式

  //定義類
    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()淺拷貝

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)深拷貝

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}};
複製程式碼

三、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"]]
複製程式碼

四、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 
複製程式碼

七、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"]
複製程式碼

八、...擴充套件運算子

物件的擴充套件運算子(...)用於取出引數物件的所有可遍歷屬性,拷貝到當前物件之中。

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}

複製程式碼

九、Object.defineProperty的作用

今天有看了一篇面試的文章,其中有一題就問到Object.defineProperty的作用,說實話,如果問我,我也答不上來,隨即百度找到了解析,然後就順便新增到此次筆記中,以便以後檢視。

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

引數說明:

obj:必需。目標物件 
prop:必需。需定義或修改的屬性的名字
descriptor:必需。目標屬性所擁有的特性
複製程式碼

針對物件到屬性,我們可以給這個屬性設定一些特性,屬性的值是否可以被重寫?比如是否只讀?;是否可以被for..in或Object.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給物件新增屬性,那麼如果不設定屬性的特性,那麼configurable、enumerable、writable這些值都為預設的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
    版權所有,歡迎保留原文連結進行轉載:) 
複製程式碼

如果你對我對文章感興趣或者有些建議想說給我聽?,也可以新增一下微信哦!

學習筆記——物件方法整理
如果親感覺我的文章還不錯的話,可以一下新增關注哦!

-----再或者感覺我的文章對您有所幫助,可以掃描二維碼打賞一下我呦!這樣我會更有動力給大家提供更優質的文章哦! 謝謝您!!!

學習筆記——物件方法整理

最後:
        祝各位工作順利!
                        -小菜鳥Christine
複製程式碼

相關文章