摘要:只獲取那些可以遍歷的屬性,使用方法對象實例的方法返回一個布爾值,用于判斷某個屬性定義在對象自身,還是定義在原型鏈上。運算符和循環運算符返回一個布爾值,表示一個對象是否具有某個屬性。
Object.getPrototypeOf()
Object.setPrototypeOf()
Object.create()
Object.prototype.isPrototypeOf()
Object.prototype.__proto__
獲取原型對象方法的比較
Object.getOwnPropertyNames()
Object.prototype.hasOwnProperty()
in 運算符和 for...in 循環
對象的拷貝
參考鏈接
1.Object.getPrototypeOf()
Object.getPrototypeOf方法返回參數對象的原型。
// 空對象的原型是 Object.prototype
Object.getPrototypeOf({}) === Object.prototype // true
// Object.prototype 的原型是 null
Object.getPrototypeOf(Object.prototype) === null // true
// 函數的原型是 Function.prototype
function f() {}
Object.getPrototypeOf(f) === Function.prototype // true
2.Object.setPrototypeOf()
Object.setPrototypeOf方法為參數對象設置原型,返回該參數對象。它接受兩個參數,第一個是現有對象,第二個是原型對象
var a = {};
var b = {x: 1};
Object.setPrototypeOf(a, b);
Object.getPrototypeOf(a) === b // true
a.x // 1
a可以共享b的屬性。
new命令可以使用Object.setPrototypeOf方法模擬。
var F = function () {
this.foo = "bar";
};
var f = new F();
// 等同于
var f = Object.setPrototypeOf({}, F.prototype);
F.call(f);
上面代碼中,new命令新建實例對象,其實可以分成兩步。第一步,將一個空對象的原型設為構造函數的prototype屬性(上例是F.prototype);第二步,將構造函數內部的this綁定這個空對象,然后執行構造函數,使得定義在this上面的方法和屬性(上例是this.foo),都轉移到這個空對象
3.Object.create()
從一個實例對象,生成另一個實例對象,new的區別是從構造函數生成。
該方法接受一個對象作為參數,然后以它為原型,返回一個實例對象。該實例完全繼承原型對象的屬性。
// 原型對象
var A = {
print: function () {
console.log("hello");
}
};
// 實例對象
var B = Object.create(A);
Object.getPrototypeOf(B) === A // true
B.print() // hello
B.print === A.print // true
上面代碼中,Object.create方法以A對象為原型,生成了B對象。B繼承了A的所有屬性和方法。
實際上,Object.create方法可以用下面的代碼代替。
if (typeof Object.create !== "function") {
Object.create = function (obj) {
function F() {} F.prototype = obj; return new F();
};
}
上面代碼表明,Object.create方法的實質是新建一個空的構造函數F,然后讓F.prototype屬性指向參數對象obj,最后返回一個F的實例,從而實現讓該實例繼承obj的屬性
下面三種方式生成的新對象是等價的。
var obj1 = Object.create({});
var obj2 = Object.create(Object.prototype);
var obj3 = new Object();
如果想要生成一個不繼承任何屬性(比如沒有toString和valueOf方法)的對象,可以將Object.create的參數設為null
使用Object.create方法的時候,必須提供對象原型,即參數不能為空,或者不是對象,否則會報錯。
Object.create()
// TypeError: Object prototype may only be an Object or null
Object.create(123)
// TypeError: Object prototype may only be an Object or null
Object.create方法還可以接受第二個參數。該參數是一個屬性描述對象,它所描述的對象屬性,會添加到實例對象,作為該對象自身的屬性。
var obj = Object.create({}, {
p1: {
value: 123, enumerable: true, configurable: true, writable: true,
},
p2: {
value: "abc", enumerable: true, configurable: true, writable: true,
}
});
// 等同于
var obj = Object.create({});
obj.p1 = 123;
obj.p2 = "abc";
4.Object.prototype.isPrototypeOf
實例對象的isPrototypeOf方法,用來判斷該對象是否為參數對象的原型
上,isPrototypeOf方法都返回true。
Object.prototype.isPrototypeOf({}) // true
Object.prototype.isPrototypeOf([]) // true
Object.prototype.isPrototypeOf(/xyz/) // true
Object.prototype.isPrototypeOf(Object.create(null)) // false
上面代碼中,由于Object.prototype處于原型鏈的最頂端,所以對各種實例都返回true,只有直接繼承自null的對象除外
5.Object.prototype.__proto_
實例對象的__proto__屬性(前后各兩個下劃線),返回該對象的原型。該屬性可讀寫
__proto__屬性只有瀏覽器才需要部署,其他環境可以沒有這個屬性。它前后的兩根下劃線,表明它本質是一個內部屬性,不應該對使用者暴露。
6.獲取原型對象方法的比較
獲取實例對象obj的原型對象,有三種方法。
obj.__proto__
obj.constructor.prototype
Object.getPrototypeOf(obj)
上面三種方法之中,前兩種都不是很可靠。__proto__屬性只有瀏覽器才需要部署,其他環境可以不部署。而obj.constructor.prototype在手動改變原型對象時,可能會失效。
__proto__屬性指向當前對象的原型對象,即構造函數的prototype屬性
var obj = new Object();
obj.__proto__ === Object.prototype
// true
obj.__proto__ === obj.constructor.prototype
// true
上面代碼首先新建了一個對象obj,它的__proto__屬性,指向構造函數(Object或obj.constructor)的prototype屬性。
7.Object.getOwnPropertyNames
Object.getOwnPropertyNames方法返回一個數組,成員是參數對象本身的所有屬性的鍵名,不包含繼承的屬性鍵名。
Object.getOwnPropertyNames(Date)
// ["parse", "arguments", "UTC", "caller", "name", "prototype", "now", "length"]
上面代碼中,Object.getOwnPropertyNames方法返回Date所有自身的屬性名。
只獲取那些可以遍歷的屬性,使用Object.keys方法
8.Object.prototype.hasOwnProperty
Object.prototype.hasOwnProperty(對象實例的hasOwnProperty方法返回一個布爾值,用于判斷某個屬性定義在對象自身,還是定義在原型鏈上。
Date.hasOwnProperty("length") // true
Date.hasOwnProperty("toString") // false
9.in 運算符和 for...in 循環
in運算符返回一個布爾值,表示一個對象是否具有某個屬性。它不區分該屬性是對象自身的屬性,還是繼承的屬性。
"length" in Date // true
"toString" in Date // true
獲得對象的所有屬性(不管是自身的還是繼承的,也不管是否可枚舉),可以使用下面的函數。
function inheritedPropertyNames(obj) {
var props = {};
while(obj) {
Object.getOwnPropertyNames(obj).forEach(function(p) { props[p] = true; }); obj = Object.getPrototypeOf(obj);
}
return Object.getOwnPropertyNames(props);
}
上面代碼依次獲取obj對象的每一級原型對象“自身”的屬性,從而獲取obj對象的“所有”屬性,不管是否可遍歷
10.對象的拷貝
如果要拷貝一個對象,需要做到下面兩件事情。
確保拷貝后的對象,與原對象具有同樣的原型。
確保拷貝后的對象,與原對象具有同樣的實例屬性。
下面就是根據上面兩點,實現的對象拷貝函數。
function copyObject(orig) {
var copy = Object.create(Object.getPrototypeOf(orig));
copyOwnPropertiesFrom(copy, orig);
return copy;
}
function copyOwnPropertiesFrom(target, source) {
Object
.getOwnPropertyNames(source) .forEach(function (propKey) { var desc = Object.getOwnPropertyDescriptor(source, propKey); Object.defineProperty(target, propKey, desc); });
return target;
}
另一種更簡單的寫法,是利用 ES2017 才引入標準的Object.getOwnPropertyDescriptors方法。
function copyObject(orig) {
return Object.create(
Object.getPrototypeOf(orig), Object.getOwnPropertyDescriptors(orig)
);
}
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105765.html
摘要:只獲取那些可以遍歷的屬性,使用方法對象實例的方法返回一個布爾值,用于判斷某個屬性定義在對象自身,還是定義在原型鏈上。運算符和循環運算符返回一個布爾值,表示一個對象是否具有某個屬性。 Object.getPrototypeOf()Object.setPrototypeOf()Object.create()Object.prototype.isPrototypeOf()Object.pro...
摘要:典型應用鎖和同步器框架的核心類,就是通過調用和實現線程的阻塞和喚醒的,而的方法實際是調用的方式來實現。 前言 Unsafe是位于sun.misc包下的一個類,主要提供一些用于執行低級別、不安全操作的方法,如直接訪問系統內存資源、自主管理內存資源等,這些方法在提升Java運行效率、增強Java語言底層資源操作能力方面起到了很大的作用。但由于Unsafe類使Java語言擁有了類似C語言指針...
摘要:先來看一個這樣的對象在函數的原型上擴展了一個方法可以看到實例化的對象下有一個屬性,而這個屬性就指向構造函數的原型對象。重點是,連接的是實例對象與構造函數原型對象,而不是,實例對象和構造函數。 前言 介紹原型的概念,和相關屬性,以及jquery判斷純凈對象的實現,不小心點進來的直接 ctrl+f 搜你想找的屬性。 什么是原型 isPrototypeOf() || Object.getP...
摘要:它不區分該屬性是對象自身的屬性,還是繼承的屬性。那么我們要遍歷對象所有屬性,包括繼承以及不可遍歷的屬性,用加原型遍歷實現類似的用遞歸 Object靜態方法 Object自身方法,必須由Object調用,實例對象并不能調用 Object.getPrototypeOf() 作用是獲取目標對象的原型 function F() {}; var obj = new F(); console.lo...
摘要:等同于構造函數與的用法很相似,幾乎一模一樣。實例對象的方法接受一個字符串作為參數,返回一個布爾值,表示該實例對象自身是否具有該屬性。等同于方法生成的對象,繼承了它的原型對象的構造函數。 分類 Object() 函數 Object 本身是一個函數,用來將任意值轉為對象。 如果參數為空(或者為 undefined 和 null),Object() 返回一個空對象。 var obj = Ob...
閱讀 702·2021-09-29 09:34
閱讀 2554·2019-08-30 15:53
閱讀 3361·2019-08-29 17:17
閱讀 761·2019-08-29 16:08
閱讀 1120·2019-08-29 13:03
閱讀 951·2019-08-27 10:54
閱讀 688·2019-08-26 13:39
閱讀 2859·2019-08-26 13:34