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 |
注意
- writable:原型對象上age屬性的writable爲false時,實例對象不可自定義該屬性;但是通過對子對象定製foo描述符,覆蓋原型上的foo對象描述符
- enumrable:表示可枚舉,就是這個屬性能否被遍歷到。
- configurable:爲true時,屬性可以被刪除;爲false時,value、writable、enumerable都不能被修改;writable只能從true改爲false,從false改爲true時會失敗。
- 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
總結
- value和get方法只能定製一個
- 一旦設置get,不能使用writable屬性
- 設置空屬性描述對象時,默認所有屬性全爲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: {…}}