日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JS-Object 对象的相关方法

發布時間:2024/4/17 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JS-Object 对象的相关方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考文章:Object 對象的相關方法

1.Object.getPrototypeOf()

Object.getPrototypeOf方法返回參數對象原型。這是獲取原型對象的標準方法

  • 下面代碼中,實例對象f的原型是F.prototype。
var F = function () {};// 構造函數 var f = new F(); Object.getPrototypeOf(f) === F.prototype // true 復制代碼
  • 下面是幾種特殊對象原型
// 空對象的原型是 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 復制代碼

上面代碼中,Object.setPrototypeOf方法將對象a的原型,設置為對象b,因此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),返回值為空對象{}賦值給變量f;
第二步,將構造函數內部的this綁定到這個空對象f,使得定義在this上面的方法和屬性(上例是this.foo),都轉移到這個空對象上。

3.Object.create()

生成實例對象的常用方法是,使用new命令讓構造函數返回一個實例對象。但我們怎么從一個實例對象,生成另一個實例對象呢?

  • JavaScript 提供了Object.create方法,用來滿足這種需求。該方法接受一個原型對象作為參數返回一個實例對象。該實例完全繼承原型對象的屬性。
// 原型對象 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方法的實質是:

(1)新建一個空的構造函數F,

(2)然后讓F.prototype屬性指向參數對象obj,

(3)最后返回一個F的實例,從而實現讓該實例繼承obj的屬性。

  • 下面三種方式生成的新對象是等價的。
var obj1 = Object.create({}); var obj2 = Object.create(Object.prototype); var obj3 = new Object(); 復制代碼
  • 如果想要生成一個不繼承任何屬性(比如沒有toString和valueOf方法)的對象,可以將Object.create的參數設為null。
var obj = Object.create(null);obj.valueOf() // TypeError: Object [object Object] has no method 'valueOf' 復制代碼

上面代碼中,對象obj的原型是null,它就不具備一些定義在Object.prototype對象上面的屬性,比如valueOf方法。

  • 使用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 obj1 = { p: 1 }; var obj2 = Object.create(obj1);obj1.p = 2; obj2.p // 2 復制代碼

上面代碼中,修改對象原型obj1會影響到實例對象obj2。

  • 除了對象的原型,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'; 復制代碼
  • Object.create方法生成的對象,繼承了它的原型對象的構造函數
function A() {} var a = new A(); var b = Object.create(a);b.constructor === A // true b instanceof A // true 復制代碼

上面代碼中,b對象的原型是a對象,因此b繼承了a對象的構造函數A。

4.Object.prototype.isPrototypeOf()

實例對象的isPrototypeOf方法,用來判斷該對象是否為參數對象的原型。

var o1 = {}; var o2 = Object.create(o1); var o3 = Object.create(o2);o2.isPrototypeOf(o3) // true o1.isPrototypeOf(o3) // true 復制代碼

上面代碼中,o1o3**的原型,o2也是o3的原型。這表明只要實例對象處在參數對象的原型鏈上,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__屬性,將p對象設為obj對象的原型。
var obj = {}; var p = {};obj.__proto__ = p; Object.getPrototypeOf(obj) === p // true 復制代碼
  • 根據語言標準,__proto__屬性只有瀏覽器才需要部署,其他環境可以沒有這個屬性。它前后的兩根下劃線,表明它本質是一個內部屬性,不應該對使用者暴露。因此,應該盡量少用這個屬性,而是應該用Object.getPrototypeof()和Object.setPrototypeOf(),進行原型對象讀寫操作。

  • 原型鏈可以用__proto__很直觀地表示。

var A = {name: '張三' }; var B = {name: '李四' };var proto = {print: function () {console.log(this.name);} };A.__proto__ = proto; B.__proto__ = proto;A.print() // 張三 B.print() // 李四A.print === B.print // true A.print === proto.print // true B.print === proto.print // true 復制代碼

上面代碼中,A對象和B對象的原型都是proto對象,它們都共享proto對象的print方法。也就是說,A和B的print方法,都是在調用proto對象的print方法。

6.獲取原型對象方法的比較

如前所述,__proto__屬性指向當前對象的原型對象,即構造函數的prototype屬性。

var obj = new Object();obj.__proto__ === Object.prototype // true obj.__proto__ === obj.constructor.prototype // true 復制代碼

上面代碼首先新建了一個對象obj,它的__proto__屬性,指向構造函數(Object或obj.constructor)的prototype屬性。

  • 因此,獲取實例對象obj的原型對象,有三種方法。
obj.__proto__ obj.constructor.prototype Object.getPrototypeOf(obj) 復制代碼

上面三種方法之中,前兩種不可靠

__proto__屬性只有瀏覽器才需要部署,其他環境可以不部署。

而obj.constructor.prototype在手動改變原型對象時,可能會失效。

下面代碼中,構造函數C的prototype 被改成了p,但是實例對象c的構造函數constructor的prototype卻沒有指向p。

var P = function () {}; var p = new P();var C = function () {}; C.prototype = p;//構造函數C的prototype 被改成了p var c = new C();c.constructor.prototype === p // false 復制代碼

所以,在改變原型對象時,一般要同時設置constructor屬性。

C.prototype = p; C.prototype.constructor = C;var c = new C(); c.constructor.prototype === p // true 復制代碼

因此,推薦使用第三種Object.getPrototypeOf方法,獲取原型對象。

7.Object.getOwnPropertyNames()

Object.getOwnPropertyNames方法返回一個數組,成員是參數對象本身的所有屬性的鍵名,不包含繼承的屬性鍵名。

Object.getOwnPropertyNames(Date) // ["parse", "arguments", "UTC", "caller", "name", "prototype", "now", "length"] 復制代碼

上面代碼中,Object.getOwnPropertyNames方法返回Date所有自身的屬性名。

對象本身的屬性之中,有的是可以遍歷的(enumerable),有的是不可以遍歷的。Object.getOwnPropertyNames方法返回所有鍵名,不管是否可以遍歷。Object.keys方法只獲取那些可以遍歷的屬性。

Object.keys(Date) // [] 復制代碼

上面代碼表明,Date對象所有自身的屬性,都是不可以遍歷的。

8.Object.prototype.hasOwnProperty()

對象實例的hasOwnProperty方法返回一個布爾值,用于判斷某個屬性定義在對象自身,還是定義在原型鏈上。

Date.hasOwnProperty('length') // true Date.hasOwnProperty('toString') // false 復制代碼

上面代碼表明,Date.length(構造函數Date可以接受多少個參數)是Date自身的屬性,Date.toString是繼承的屬性。

另外,hasOwnProperty方法是 JavaScript 之中唯一一個處理對象屬性時,不會遍歷原型鏈的方法。

9. in 運算符和 for...in 循環

  • in運算符返回一個布爾值,表示一個對象是否具有某個屬性。它不區分該屬性是對象自身的屬性,還是繼承的屬性。
'length' in Date // true 'toString' in Date // true 復制代碼

in運算符常用于檢查一個屬性是否存在

  • 獲得對象的所有可遍歷屬性(不管是自身的還是繼承的),可以使用for...in循環。
var o1 = { p1: 123 };var o2 = Object.create(o1, {p2: { value: "abc", enumerable: true } });for (p in o2) {console.info(p); } // p2 // p1 復制代碼

上面代碼中,對象o2的p2屬性是自身的,p1屬性是繼承的。這兩個屬性都會被for...in循環遍歷。

  • 為了在for...in循環中獲得對象自身的屬性,可以采用hasOwnProperty方法判斷一下。
for ( var name in object ) {if ( object.hasOwnProperty(name) ) {/* loop code */} } 復制代碼
  • 獲得對象的所有屬性(不管是自身的還是繼承的,也不管是否可枚舉),可以使用下面的函數。
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對象的“所有”屬性,不管是否可遍歷。

下面是一個例子,列出Date對象的所有屬性。

inheritedPropertyNames(Date) // [ // "caller", // "constructor", // "toString", // "UTC", // ... // ] 復制代碼

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);//通過屬性描述對象desc,定義target對象上的屬性propKeyObject.defineProperty(target, propKey, desc);});return target; } 復制代碼

另一種更簡單的寫法,是利用 ES2017 才引入標準的Object.getOwnPropertyDescriptors方法。

function copyObject(orig) {return Object.create(Object.getPrototypeOf(orig),//獲取orig對象的原型對象Object.getOwnPropertyDescriptors(orig)); } 復制代碼

總結

以上是生活随笔為你收集整理的JS-Object 对象的相关方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。