Object對象方法總結

Object對象方法總結

主要是Object對象上的方法,以及其創建的實例上方法。 通常可以用在不同實例對象上的方法。

Object方法

Object.assign(targetObj,copyObg)

將一個對象上的方法拷貝到另一個對象上

function Fruit(name) { 
    this.name = name;
}
Fruit.prototype.sayName = function () { 
    console.log(this.name);
}
var Apple = {
    color:"red"
}
var ft = new Fruit("apple");
Object.assign(Apple,ft);  // 將ft對象上的屬性和方法複製到Apple上
console.log(Apple);

Object.keys()

獲取對象所有(可枚舉)屬性名的數組,對象原型上的屬性不能獲取。

function Plant(){
    this.desc = "植物類"
}
Plant.prototype.sayHi = function () { 
    console.log("hi");
}
function Apple() { 
    this.desc = "我是一個大蘋果";
    Plant.call(this);
}
Apple.prototype = Object.create(Plant.prototype);
Apple.prototype.constructor = Apple;

// 使用Object.keys()
var bigApple = new Apple();
console.log(bigApple);  // Apple{desc: "植物類"}
console.log(Object.keys(bigApple));  // ["desc"]

Object.getOwnPropertyNames()

獲取對象本身的屬性,不包括對象原型上的屬性
console.log(Object.getOwnPropertyNames(bigApple)); // ["desc"]

Object.getPrototypeOf()

獲取對象的原型

function Plant(){
    this.desc = "植物類"
}
var obj = new Plant();
console.log(obj.__proto__ === Object.getPrototypeOf(obj)); // true
console.log(Plant.prototype === Object.getPrototypeOf(obj))// true

等價於實例的__proto__屬性

Object.setPrototypeOf()

設置對象的原型

// 創建兩個對象
var obj1 = {
    name:"obj1"
};
var obj2 = {
    age:18
}
Object.setPrototypeOf(obj1,obj2);
console.log(Object.getPrototypeOf(obj1) === obj2);  // true

將obj1對象的原型設置爲obj2

new原理

new一個對象的原理其實是:
1.創建一個空對象obj
2.將該對象原型設置爲Plant.prototype
3.使用構造函數Plant初始化對象。(調用構造函數修改this指向爲obj對象即可)

function Plant(){
    this.desc = "植物類"
}
// var plt = new Plant;
var obj = {};
Object.setPrototypeOf(obj,Plant.prototype);
Plant.call(obj);
console.log(obj.desc);  // 植物類
console.log(obj instanceof Plant);  // true

Object.create()

傳入一個對象,以這個對象爲原型創建一個新對象

var obj1 = {
    name:"obj1"
};
var obj2 = Object.create(obj1);
// getPrototypeOf查看原型對象
console.log(Object.getPrototypeOf(obj2) === obj1);  // true

Object實例方法

對象實例上的方法

valueOf()

只有在計算式中,對象調用這個方法,將對象轉換成值

var obj1 = {
    name:"obj1"
};
console.log(obj1.valueOf());  // {name: "obj1"}  
obj1.valueOf = function () { 
    return 3;
}
console.log(obj1+2);   // 5

toString()和toLocaleString()

返回一個對象的字符串形式,默認返回類型字符串

var obj1 = {
    name:"obj1"
};
function fn() {  };
var date = new Date();
console.log(obj1.toString());  // [object Object]  對象-》對象類型
console.log(String("33").toString());  // 33  字符串=》字符串本身
console.log(Number(128).toString());  // 128  數字=》值
console.log([1,3,5].toString());  // 1,3,5    數組=》使用,連接每個數組每個元素,相當於調用join(",")
console.log(fn.toString());  //  function fn() {  }  函數=》函數內容
console.log(date.toString());  // Sat May 09 2020 19:09:55 GMT+0800 (中國標準時間)  時間=》時間戳

對於不同類型的對象,返回不同的值

toLocaleString

使用本地的習慣定義返回值。通常對時間、數組、數字定製了該方法

// toLocalString
console.log(Number(128).toLocaleString());  // 128  
console.log([1,3,5].toLocaleString());  // 1,3,5   
console.log(date.toLocaleString());  // 2020/5/9 下午7:13:24  時間=》時間戳   使用當地習慣的時間表示方法

isPrototypeof()

判斷a是否是b的原型

var obj1 = {
    name:"obj1"
};
var obj2 = {
    age:18
}
Object.setPrototypeOf(obj1,obj2);  // 設置obj1的原型是obj2
console.log(obj2.isPrototypeOf(obj1));  // true
console.log(Object.prototype.isPrototypeOf(obj1));  // true  Object.prototype是obj1的原型

其實,根據原型鏈解釋,Object.prototype是所有對象的原型對象。

hasOwnProperty()

判斷該實例是否有自己的屬性

var obj1 = {
    name:"obj1"
};
var obj2 = {
    age:18
}
Object.setPrototypeOf(obj1,obj2);  // 設置obj1的原型是obj2
console.log(obj1.hasOwnProperty("name"));  // true
console.log(obj1.hasOwnProperty("age"));  // false

這個方法是用來判斷一個屬性是否是該對象自己的方法,而不是繼承過來的方法。

屬性對象描述符

屬性對象描述符,通常是用來控制對象的一個屬性是否可以修改、刪除、枚舉等操作。

Object.getOwnPropertyDescriptor()

獲取對象上的一個屬性的屬性描述符
參數一爲一個對象,參數二爲對象上的一個屬性

var obj1 = {
    name:"haha"
}
// 查看obj1對象的name屬性的屬性描述符
console.log(Object.getOwnPropertyDescriptor(obj1,"name"));
//結果{value: "haha", writable: true, enumerable: true, configurable: true}
console.log(obj1.propertyIsEnumerable("name"));  // true

Object.getOwnPropertyNames()

獲取可枚舉屬性和不可遍歷的屬性

var obj1 = {
    name:"haha"
}
Object.defineProperty(obj1,"age",{
    value:18,
    writable:false,
    enumerable:true
})
console.log(Object.getOwnPropertyNames(obj1));  // ["name", "age"]

propertyIsEnumerable()

判斷對象是否可枚舉,只能判斷對象本身的屬性,不可枚舉的屬性或者繼承的屬性一律返回false
具體可設置的屬性如下

屬性名 作用
value “haha” 對象的值
writable true 設置該屬性是否可寫
enumerable true 設置該屬性是否可枚舉(例如:for in遍歷對象時,遍歷到這個屬性)
configurable true 是否可配置,對象能否刪除
set undefined 設置對象屬性時調用,例如:obj.name=123
get undefined 獲取對象屬性時調用,例如:obj.name

注意

  1. writable:原型對象上age屬性的writable爲false時,實例對象不可自定義該屬性;但是通過對子對象定製foo描述符,覆蓋原型上的foo對象描述符
  2. enumrable:表示可枚舉,就是這個屬性能否被遍歷到。
  3. configurable:爲true時,屬性可以被刪除;爲false時,value、writable、enumerable都不能被修改;writable只能從true改爲false,從false改爲true時會失敗。
  4. value:只要writable和configurable有一個爲true,就允許被修改

defineProperty()

定義對象上屬性的屬性描述符
參數爲對象,參數二爲屬性,參數三爲對象描述符

var obj1 = {
    name:"haha"
}
Object.defineProperty(obj1,"age",{
    value:18,
    writable:false,
    enumerable:true
})
console.log(Object.getOwnPropertyDescriptor(obj1,"age"));
//結果:{value: 18, writable: false, enumerable: true, configurable: false}

對於沒有定義的屬性描述符,默認爲false

defineProperties()

定義多個對象屬性的屬性描述符
參數一爲對象,參數二爲鍵值對列表(鍵爲屬性名,值爲屬性描述符)

var obj1 = {
    name:"haha"
}
Object.defineProperties(obj1,{
    p1:{
        value:"hello",
        writable:true
    },
    p2:{
        get:function () { 
            return this.name + " is sb"
        },
        set:function(newVal){
            console.log("set");
            this.name = newVal
        }
    }
})
console.log(Object.getOwnPropertyDescriptor(obj1,"p1"));  
// {value: "hello", writable: true, enumerable: false, configurable: false}
console.log(Object.getOwnPropertyDescriptor(obj1,"p2"));
// {enumerable: false, configurable: false, get: ƒ, set: ƒ}
console.log(obj1.p2);  // haha is sb
obj1.p2 = "apple";  // set

總結

  1. value和get方法只能定製一個
  2. 一旦設置get,不能使用writable屬性
  3. 設置空屬性描述對象時,默認所有屬性全爲false

案例:使用Object方法實現對象的深拷貝

淺拷貝和深拷貝簡介

js有基本數據類型和引用數據類型

深拷貝

基本數據類型使用等號,直接複製對象

let a = 22;
let b = a;
b = 4;
console.log(a);  // 22
console.log(b);  // 4

b複製了a的值之後,與原對象a就沒有任何關係。b的值修改,a的值也不會變。

淺拷貝

如果是引用類型(對象、數組),直接複製,變量獲得的是對象的內存地址,而不是對象的值

// 案例一
let arr1 = [1,4,5];
let arr2 = arr1;
arr2.push(66);
console.log(arr1);  // [1, 4, 5, 66]
console.log(arr2);  // [1, 4, 5, 66]
// 案例二
let obj1 = {
    name:"apple",
    age:12
};
let obj2 = obj1;
obj2.name = "banana";
console.log(obj1);  // {name: "banana", age: 12}
console.log(obj2);  // {name: "banana", age: 12}

實現方法

對對象的屬性依次遍歷,判斷是否是一個對象,是則遞歸遍歷;不是,則複製到新對象上。

function deepCopy(oldObj,newObj) { //oldObj:被複制的對象  newObj:新對象,複製到這個對象中
    for(key in oldObj){
        // hasOwnProperty判斷這個屬性是否是自己的屬性,而不是繼承過來的
        if(oldObj.hasOwnProperty(key)){
            if(oldObj[key] && typeof oldObj[key] === "object"){
                // 判斷是數組還是對象
                newObj[key] = oldObj[key].constructor === Array?[]:{};
                // 繼續遞歸,將數組/對象中的值賦值到新對象中
                deepCopy(oldObj[key],newObj[key]);

            }else{  // 如果是一個屬性,則直接複製到新對象
                newObj[key] = oldObj[key];
            }
        }

    }
    return newObj
}
var obj1 = {
    name:"apple",
    color:['blue','green'],
    prop:{
        num:12
    }
};
var obj2 = deepCopy(obj1,{});
console.log(obj1);  // {name: "apple", color: Array(2), prop: {…}}
console.log(obj2);  // {name: "apple", color: Array(2), prop: {…}}
obj2.name = "banana";
obj2.color.pop();
console.log(obj1);  // {name: "apple", color: Array(2), prop: {…}}
console.log(obj2);  // {name: "banana", color: Array(1), prop: {…}}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章