056_Object对象方法
1. 對象屬性值
1.1. 所有屬性都有名稱, 此外它們還有值。
1.2. 值是屬性的特性之一。
1.3. 其他特性包括: 可枚舉、可配置、可寫。
1.4. 在JavaScript中, 所有屬性都是可讀的, 但是只有屬性可寫時才可修改的。
2. Object.defineProperty()方法
2.1. Object.defineProperty(obj, prop, descriptor)方法會直接在一個對象上定義一個新屬性, 或者修改一個現有屬性, 并返回此對象。
2.2. 參數
2.2.1. obj: 要定義屬性的對象。
2.2.2. prop: 要定義或修改的屬性的名稱。
2.2.3. descriptor: 要定義或修改的屬性描述符。
2.3. 對象里目前存在的屬性描述符有兩種主要形式: 數據描述符和存取描述符。一個描述符只能是這兩者其中之一, 不能兩者同時存在。
2.4. 這兩種描述符都是對象。它們共享以下可選鍵值:
2.4.1. configurable: 屬性是否可重新配置。當且僅當該屬性的configurable鍵值為true時, 該屬性的描述符才能夠被改變, 同時該屬性也能從對應的對象上被刪除(可以使用delete運算符刪除屬性從而重新定義屬性)。默認為false。
2.4.2. enumerable: 屬性可枚舉(用到for...in或Object.keys方法)。默認為false。
2.5. 數據描述符具有以下可選鍵值:
2.5.1. value: 與屬性關聯的值。默認為undefined。
2.5.2. writable: 屬性是否可寫。當且僅當該屬性的writable鍵值為true時, 屬性的值, 也就是上面的value, 才能被賦值運算符改變。默認為false。
2.6. 存取描述符還具有以下可選鍵值:
2.6.1. get: 屬性的getter函數, 如果沒有getter, 則為undefined。當訪問該屬性時, 會調用此函數。執行時不傳入任何參數, 但是會傳入this對象(由于繼承關系, 這里的this并不一定是定義該屬性的對象)。該函數的返回值會被用作屬性的值。默認為undefined。
2.6.2. set: 屬性的setter函數, 如果沒有setter, 則為undefined。當屬性值被修改時, 會調用此函數。該方法接受一個參數(也就是被賦予的新值), 會傳入賦值時的this對象。默認為undefined。
3. Object.defineProperties()方法
3.1. Object.defineProperties(obj, props)方法直接在一個對象上定義新的屬性或修改現有屬性(可以是多個屬性), 并返回該對象。
3.2. 參數
3.2.1. obj: 要定義屬性的對象。
3.2.2. props: 要定義或修改的屬性和描述符的集合(更多詳情, 請參閱Object.defineProperty())。
4. Object.getOwnPropertyDescriptor()方法
4.1. Object.getOwnPropertyDescriptor(obj, prop)方法返回指定對象上一個自有屬性(自有屬性指的是直接賦予該對象的屬性, 不需要從原型鏈上進行查找的屬性)對應的屬性描述符。
4.2. 參數
4.2.1. obj: 需要查找的目標對象。
4.2.2. prop: 目標對象內屬性名稱。
4.3. 返回值
4.3.1. 如果指定的屬性存在于對象上, 則返回其屬性描述符對象(property descriptor), 否則返回undefined。
5. Object.getOwnPropertyDescriptors()方法
5.1. Object.getOwnPropertyDescriptors(obj)方法用來獲取一個對象的所有自身屬性的描述符。
5.2. 參數
5.2.1. obj: 任意對象
5.3. 返回值
5.3.1. 所指定對象的所有自身屬性的描述符, 如果沒有任何自身屬性, 則返回空對象。
5.4. 例子
5.4.1. 代碼
<!DOCTYPE html> <html><head><meta charset="utf-8" /><title>Object.defineProperty()、Object.defineProperties()、Object.getOwnPropertyDescriptor()和Object.getOwnPropertyDescriptors()方法</title></head><body><script type="text/javascript">var person = {};Object.defineProperty(person, "_language_", {enumerable: false, configurable: true, value: "en", writable: true});Object.defineProperties(person, {"id": {enumerable: true, configurable: false, value: 1001, writable: true},"name": {enumerable: true, configurable: false, value: 'zhang san', writable: false},"age": {enumerable: true, configurable: true, value: 18, writable: true},"address": {enumerable: true, configurable: true, value: "bei jing", writable: false},"telephone": {enumerable: true, configurable: false, value: 13552460001, writable: true},"sex": {enumerable: true, configurable: false, value: 'female', writable: true}});var descriptorss = Object.getOwnPropertyDescriptors(person);for(let key in descriptorss) {document.write(key + ': ');for(let item in descriptorss[key]) {document.write(item + ': ' + descriptorss[key][item] + '\t');}document.write('<br />');}document.write('<hr />');// writable為true, 才可以通過賦值運算符重新賦值person.id = 1002; // 賦值成功person.name = '張三'; // 賦值失敗person.age = 16; // 賦值成功person.address = '河南'; // 賦值失敗person.telephone = 13552460002; // 賦值成功person.sex = 'male'; // 賦值成功for(let item in person) {document.write(item + ': ' + person[item] + '<br />');}document.write('<hr />');// configurable為true, 才可以修改描述符Object.defineProperty(person, "address", {enumerable: true, configurable: false, value: "洛陽", writable: true});Object.defineProperty(person, "Language", {enumerable: false, configurable: false, get: function(){return this._language_;}, set: function(newValue){this._language_ = newValue;}});document.write(person.Language + '<br />');person.Language = 'zh';document.write(person.Language + '<hr />');var descriptors1 = Object.getOwnPropertyDescriptors(person);for(let key in descriptors1) {document.write(key + ': ');for(let item in descriptors1[key]) {document.write(item + ': ' + descriptors1[key][item] + '\t');}document.write('<br />');}document.write('<hr />');// configurable為false, writable為true, 可以value數據描述符Object.defineProperty(person, "id", {enumerable: true, configurable: false, value: 1003, writable: true});// configurable為false, 不能修改enumerable描述符try {Object.defineProperty(person, "telephone", {enumerable: false, configurable: false, value: 13552460002, writable: true});} catch (e) {document.write(e + '<hr />');}// configurable為true, 才可以刪除屬性delete person.id; // 刪除失敗delete person.name; // 刪除失敗delete person.age; // 刪除成功delete person.language; // 刪除失敗delete person.address; // 刪除失敗delete person.telephone; // 刪除失敗delete person.sex; // 刪除失敗var descriptors2 = Object.getOwnPropertyDescriptors(person);for(let key in descriptors2) {document.write(key + ': ');for(let item in descriptors2[key]) {document.write(item + ': ' + descriptors2[key][item] + '\t');}document.write('<br />');}document.write('<hr />');var descriptors = Object.getOwnPropertyDescriptor(person, 'name');for(let item in descriptors) {document.write(item + ': ' + descriptors[item] + '<br />');}</script></body> </html>5.4.2. 效果圖
6. Object.create()方法
6.1. Object.create(proto, [propertiesObject])方法創建一個新對象, 使用現有的對象來提供新創建的對象的__proto__。返回一個新對象, 帶著指定的原型對象和屬性。
6.2. 參數
6.2.1. proto: 新創建對象的原型對象。
6.2.2. propertiesObject: 可選。需要傳入一個對象, 該對象的屬性類型參照Object.defineProperties()的第二個參數。如果該參數被指定且不為undefined, 該傳入對象的自有可枚舉屬性(即其自身定義的屬性, 而不是其原型鏈上的枚舉屬性)將為新創建的對象添加指定的屬性值和對應的屬性描述符。
6.3. 例子
6.3.1. 代碼
<!DOCTYPE html> <html><head><meta charset="utf-8" /><title>Object.create()方法</title></head><body><script type="text/javascript">// 創建一個原型為null的空對象var emptyObj = Object.create(null);var textObj = {};// 以文本方式創建的空對象就相當于var obj = Object.create(Object.prototype);// 以對象作為新對象的原型var person = {id: 1001, name: 'zs', print: function(){return '[id: ' + this.id + ', name: ' + this.name + ']';}};var personObj = Object.create(person);document.write(personObj.print() + '<br />');// create實現繼承function Shape(x, y) {this.x = x;this.y = y;}Shape.prototype.move = function(x, y) {this.x += x;this.y += y;};function Rectangle(x, y) {Shape.call(this, x, y); }Rectangle.prototype = Object.create(Shape.prototype);var rect = new Rectangle(7, 8);document.write('rect對象是Rectangle類的實例: ' + (rect instanceof Rectangle) + '<br />'); document.write('rect對象是Shape類的實例: ' + (rect instanceof Shape) + '<br />'); document.write('Rectangle.prototype對象在rect對象的原型鏈上: ' + (Rectangle.prototype.isPrototypeOf(rect)) + '<br />');document.write('Shape.prototype對象在rect對象的原型鏈上: ' + (Shape.prototype.isPrototypeOf(rect)) + '<br />');rect.move(1, 1);document.write('x = ' + rect.x + ', y = ' + rect.y + '<br />');// 創建一個帶屬性的對象var paramObj = Object.create(Object.prototype, {foo: {enumerable: true,writable: true,configurable: true,value: "foofoo"},bar: {enumerable: true,configurable: true,value: "barbar"}});for(let item in paramObj) {document.write(item + ': ' + paramObj[item] + '<br />');}</script></body> </html>6.3.2. 效果圖
7. Object.getOwnPropertyNames()方法
7.1. Object.getOwnPropertyNames(obj)方法返回一個由指定對象的所有自身屬性的屬性名(包括不可枚舉屬性, 不包括原型上的屬性)組成的數組。
7.2. 參數
7.2.1. obj: 需要查找的目標對象。
7.3. 返回值
7.3.1. 在給定對象上找到的自身屬性對應的字符串數組。
8. Object.keys()方法
8.1. Object.keys(obj)方法會返回一個由給定對象的自身可枚舉屬性組成的數組, 數組中屬性名的排列順序和正常循環遍歷該對象時返回的順序一致。
8.2. 參數
8.2.1. obj: 需要查找的目標對象。
8.3. 返回值
8.3.1. 一個表示給定對象的所有可枚舉屬性的字符串數組。
9. Object.getPrototypeOf()方法
9.1. Object.getPrototypeOf(obj)方法返回指定對象的原型。
9.2. 參數
9.2.1. obj: 需要查找的目標對象。
10. Object.setPrototypeOf()方法
10.1. Object.setPrototypeOf(obj, prototype)方法設置一個指定的對象的原型到另一個對象或null。
10.2. 參數
10.2.1. obj: 要設置其原型的對象。
10.2.2. prototype: 該對象的新原型(一個對象或null)。
10.3. 警告: 由于現代JavaScript引擎優化屬性訪問所帶來的特性的關系, 更改對象的[[Prototype]]在各個瀏覽器和JavaScript引擎上都是一個很慢的操作。其在更改繼承的性能上的影響是微妙而又廣泛的, 這不僅僅限于 obj.__proto__ = ... 語句上的時間花費, 而且可能會延伸到任何代碼, 那些可以訪問任何[[Prototype]]已被更改的對象的代碼。如果你關心性能, 你應該避免設置一個對象的[[Prototype]]。相反, 你應該使用 Object.create()來創建帶有你想要的[[Prototype]]的新對象。
11. Object.preventExtensions()方法
11.1. Object.preventExtensions(obj)方法讓一個對象變的不可擴展, 也就是永遠不能再添加新的屬性。
11.2. 參數
11.2.1. obj: 將要變得不可擴展的對象。
11.3. 返回值
11.3.1. 已經不可擴展的對象。
11.4. 如果一個對象可以添加新的屬性, 則這個對象是可擴展的。Object.preventExtensions()將對象標記為不再可擴展, 這樣它將永遠不會具有它被標記為不可擴展時持有的屬性之外的屬性。注意, 一般來說, 不可擴展對象的屬性可能仍然可被刪除。嘗試將新屬性添加到不可擴展對象將拋出TypeError。
11.5. Object.preventExtensions()僅阻止添加自身的屬性。但其對象類型的原型依然可以添加新的屬性。
11.6. 該方法使得目標對象的[[prototype]]本身不可變; 任何重新賦值[[prototype]]操作都會拋出TypeError。但原型的屬性可以修改。
12. Object.isExtensible(object)方法
12.1. Object.isExtensible(object)方法判斷一個對象是否是可擴展的(是否可以在它上面添加新的屬性)。
12.2. 參數
12.2.1. obj: 需要查找的目標對象。
12.3. 返回值
12.3.1. 表示給定對象是否可擴展的一個Boolean。
13. Object.seal()方法
13.1. Object.seal(obj)方法封閉一個對象, 阻止添加新屬性并將所有現有屬性標記為不可配置。當前屬性的值只要原來是可寫的就可以改變。此外, 封閉一個對象后該對象的原型本身不能被修改, 但原型的屬性可以修改。
13.2. 參數
13.2.1. obj: 需要查找的目標對象。
14. Object.isSealed()方法
14.1. Object.isSealed(obj)方法判斷一個對象是否被密封。
14.2. 參數
14.2.1. obj: 需要查找的目標對象。
14.3. 返回值
14.3.1. 表示給定對象是否被密封的一個Boolean 。
15. Object.freeze(object)方法
15.1. Object.freeze(object)方法可以凍結一個對象。一個被凍結的對象再也不能被修改。凍結了一個對象則不能向這個對象添加新的屬性, 不能刪除已有屬性, 不能修改該對象已有屬性的可枚舉性、可配置性、可寫性, 以及不能修改已有屬性的值。此外, 凍結一個對象后該對象的原型本身不能被修改,?但原型的屬性可以修改。如果一個屬性的值是個對象, 則這個對象中的屬性是可以修改的, 除非它也是個凍結對象(淺凍結)。
15.2. 參數
15.2.1. obj: 要被凍結的對象。
15.3. 返回值
15.3.1. 返回和傳入的參數相同的被凍結的對象。
16. Object.isFrozen()方法
16.1. Object.isFrozen(object)方法判斷一個對象是否被凍結。
16.2. 參數
16.2.1. obj: 需要查找的目標對象。
16.3. 返回值
16.3.1. 表示給定對象是否被凍結的Boolean。
16.4. 一個空對象, 設置為不可擴展或密封, 也是一個凍結對象。
17. 例子
17.1. 代碼
<!DOCTYPE html> <html><head><meta charset="utf-8" /><title>Object對象方法</title></head><body><script type="text/javascript">var person = Object.create(Object.prototype);Object.defineProperty(person, "language", {enumerable: true, configurable: true, value: "en", writable: true});Object.defineProperties(person, {"id": {enumerable: true, configurable: true, value: 1001, writable: true},"name": {enumerable: true, configurable: true, value: 'zhang san', writable: true},"age": {enumerable: true, configurable: true, value: 18, writable: true},"address": {enumerable: true, configurable: true, value: "bei jing", writable: true},"telephone": {enumerable: true, configurable: true, value: 13552460001, writable: true},"sex": {enumerable: false, configurable: true, value: 'female', writable: true}});for(let item in person) {document.write(item + ': ' + person[item] + '<br />');}document.write('<hr />');// Object.getOwnPropertyNames()方法返回一個由指定對象的所有自身屬性的屬性名(包括不可枚舉屬性, 不包括原型上的屬性/方法)組成的數組person.__proto__.run = function(){document.write('我會跑的.' + '<br />');};document.write(Object.getOwnPropertyNames(person) + '<br />');document.write('<hr />');// Object.keys()方法會返回一個由給定對象的自身可枚舉屬性組成的數組document.write(Object.keys(person) + '<br />');document.write('<hr />');// Object.getPrototypeOf()方法返回指定對象的原型var prototype = Object.getPrototypeOf(person);prototype.myToString = function(){return '[id=' + this.id + ',name=' + this.name + ',age=' + this.age + ',address=' + this.address + ',telephone=' + this.telephone + ',sex=' + this.sex + ',language=' + this.language + ']';};document.write(person.myToString() + '<br />');// Object.setPrototypeOf()方法設置一個指定的對象的原型到另一個對象或nullObject.setPrototypeOf(person, null);Object.setPrototypeOf(person, Object.prototype);document.write('<hr />');// Object.preventExtensions()方法讓一個對象變的不可擴展, 也就是永遠不能再添加新的屬性。document.write('person是否可擴展: ' + Object.isExtensible(person) + '<br />');Object.preventExtensions(person);document.write('person是否可擴展: ' + Object.isExtensible(person) + '<br />');try {// 對象設置為不可擴展, 添加新屬性拋異常Object.defineProperty(person, "weight", { value: 8675309 });} catch(e) {document.write(e + '<br />');}// 對象設置為不可擴展, 可以給原型上添加方法person.__proto__.eat = function(){document.write('我會吃的.' + '<br />');};// 對象設置為不可擴展, 賦值的方式添加新屬性, 添加不上, 無異常person.height = 177;try {// 對象設置為不可擴展, 設置新的原型拋異常Object.setPrototypeOf(person, null);} catch(e) {document.write(e + '<br />');}// 對象設置為不可擴展, 還可以重新配置屬性Object.defineProperty(person, "language", {writable: false});// 對象設置為不可擴展, 屬性還可以是可寫的person.name = '張三';// 對象設置為不可擴展, 屬性還可以是可刪除的(可重新配置)delete person.sex;delete person.__proto__.myToString;document.write('<hr />');var descriptors1 = Object.getOwnPropertyDescriptors(person);for(let key in descriptors1) {document.write(key + ': ');for(let item in descriptors1[key]) {document.write(item + ': ' + descriptors1[key][item] + '\t');}document.write('<br />');}document.write('<hr />');// Object.seal()方法封閉一個對象, 阻止添加新屬性并將所有現有屬性標記為不可配置。當前屬性的值只要原來是可寫的就可以改變document.write('person是否密封: ' + Object.isSealed(person) + '<br />');Object.seal(person);document.write('person是否密封: ' + Object.isSealed(person) + '<br />');// 對象設置為密封, 不能刪除屬性delete person.telephone;// 原型鏈上的方法可刪除(同時, 原型鏈上還是可以添加和修改方法的)delete person.__proto__.run;// 對象設置為密封, 可以給原型上添加方法person.__proto__.drank = function(){document.write('我會喝的.' + '<br />');};try {// 對象設置為密封, 不可以重新配置屬性Object.defineProperty(person, "language", {enumerable: false, configurable: false, writable: false});} catch(e) {document.write(e + '<br />');}// 對象設置為密封, 屬性可寫person.id = '1002';Object.defineProperty(person, "address", {value: "河北"});document.write('<hr />');var descriptors2 = Object.getOwnPropertyDescriptors(person);for(let key in descriptors2) {document.write(key + ': ');for(let item in descriptors2[key]) {document.write(item + ': ' + descriptors2[key][item] + '\t');}document.write('<br />');}document.write('<hr />');// Object.freeze()方法可以凍結一個對象document.write('person是否凍結: ' + Object.isFrozen(person) + '<br />');Object.freeze(person);document.write('person是否凍結: ' + Object.isFrozen(person) + '<br />');// 一個空對象, 設置為不可擴展或密封, 也是一個凍結對象var emptyObj1 = {};document.write('emptyObj1是否凍結: ' + Object.isFrozen(emptyObj1) + '<br />');Object.preventExtensions(emptyObj1);document.write('emptyObj1是否凍結: ' + Object.isFrozen(emptyObj1) + '<br />');var emptyObj2 = {};document.write('emptyObj2是否凍結: ' + Object.isFrozen(emptyObj2) + '<br />');Object.seal(emptyObj2);document.write('emptyObj2是否凍結: ' + Object.isFrozen(emptyObj2) + '<br />');// 對象設置為凍結, 不能刪除屬性delete person.address;// 原型鏈上的方法可刪除(同時, 原型鏈上還是可以添加和修改方法的)delete person.__proto__.eat;try {// 對象設置為凍結, 屬性不可寫Object.defineProperty(person, "address", {value: "洛陽", writable: true});} catch(e) {document.write(e + '<br />');}document.write('<hr />');var descriptors3 = Object.getOwnPropertyDescriptors(person);for(let key in descriptors3) {document.write(key + ': ');for(let item in descriptors3[key]) {document.write(item + ': ' + descriptors3[key][item] + '\t');}document.write('<br />');}document.write('<br />');</script></body> </html>17.2. 效果圖
總結
以上是生活随笔為你收集整理的056_Object对象方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 047_Object对象
- 下一篇: 078_弹出框