摘要:需要鏈接標準參考教程對象阮一峰標準構造器函數可能是最重要的對象之一,盡管我們從來不會直接調用它。該方法返回被凍結的對象。
Object 需要鏈接: MDN —— Object JavaScript標準參考教程(Object對象)——阮一峰
標準構造器函數Object可能是JavaScript最重要的對象之一,盡管我們從來不會直接調用它。每當使用一個對象直接量時,都會隱式調用它:
var a = {}; // 等同于var a = new Object() var b = {x:1,y:2}; // 等同于var b = new Object({x:1,y:2});
構造函數定義了數據類型,所以表達式var a = new Object()表明兩件事情:a是Object的一個實例,而a的原型是Object.prototype。我們用對象字面量創建的每個對象都會獲得由Object.prototype定義的行為
以下將討論幾個常用的主要的屬性方法 1. Object()// 首先,將Object作為構造函數調用和對象字面量直接定義是等價的 var o = {}; var o2 = new Object(); // 注意這里所說的等價不是指相等,是指其本身和原型繼承相同 // 當然也可以 var a = {}; var a2 = new Object(a); console.log(a===a2); // trueObject本身作為工具方法
// 返回一個Object構造器實例 var obj = Object(); console.log(obj instanceof Object); // true // 返回一個字符串構造器實例 var str = Object("string"); console.log(str instanceof Object); // true 等價 new String("string") // 返回一個數字構造器實例 var num = Object(123); console.log(num instanceof Object); // true 等價 new Number(123) // 返回一個布爾構造器實例 var boo = Object(true); // 等價 new Boolean(true) var boo2 = Object(false); console.log(boo instanceof Object && boo2 instanceof Object); // true // null存在的意義在于對象引用之中,null值最初含義為:沒有引用任何對象 // null型只能取null一個值,null值是一個字面量,但是對null進行typeof結果為對象 console.log(typeof null); // object console.log(Object(null) instanceof Object); // true // 對null調用Object方法,返回一個空對象 // undefined型也只能取undefined一個值,對undefined進行typeof ,值為undefined console.log(typeof undefined); // undefined console.log(Object(undefined) instanceof Object); // true // 也是返回一個空對象
Object()傳入參數為基本類型值,則返回值為其類型的構造函數的實例。Object本身當作工具方法使用時,可以將任意值轉為對象。這個方法常用于保證某個值一定是對象。如果參數是原始類型的值,Object方法返回對應的包裝對象的實例
上面探討的是基礎類型值,那如果是引用類型值呢?
var arr = [1,2,3]; console.log(Object(arr)); // 把原對象返回了 console.log(Object(arr)===arr); // true var fn = function () {}; // 把原函數返回了 console.log(Object(fn)); // function () {} console.log(Object(fn)===fn); // true var obj = {x:"obj.x"}; console.log(Object(obj)); // [object Object] console.log(Object(obj)===obj); // true // 一個判斷是否是對象的函數 function judgeObj(obj) { return Object(obj)===obj? true : false; } console.log(judgeObj([])); // true console.log(judgeObj(true)); // false console.log(judgeObj({})); // true console.log(judgeObj(123)); // false當Object()傳入的參數是引用類型值,則會返回原對象; 2. Object.keys(obj)
受Enumerable條件限制,且不可枚舉原型鏈中的屬性Object.keys() 方法會返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組中屬性名的排列順序和使用 for...in 循環遍歷該對象時返回的順序一致 (兩者的主要區別是 一個 for-in 循環還會枚舉其原型鏈上的屬性)。
// 無法枚舉到原型鏈中的屬性 var obj = Object.create({y:20}); obj.x = 10; console.log(Object.keys(obj)); // "x" // 無法枚舉Enumerable為false屬性 Object.defineProperty(obj,"z",{ value:"z", enumerable:false }) console.log(Object.keys(obj)); // "x" // 對于數組對象 var arr = ["a","b","c"]; console.log(Object.keys(arr)); // "0,1,2" // 對于隨機排列的數組對象 var obj_ramdom = {100:"a",2:"b",50:"c"}; console.log(Object.keys(obj_ramdom)); // "2,50,100"詳細說明:MDN —— Object.keys() 3. Object.getOwnPropertyNames(obj)
不受Enumerable條件限制,但不可枚舉原型鏈中屬性Object.getOwnPropertyNames 返回一個數組,該數組對元素是 obj 自身擁有的枚舉或不可枚舉屬性名稱字符串。 數組中枚舉屬性的順序與通過 for...in 循環(或 Object.keys)迭代該對象屬性時一致。 數組中不可枚舉屬性的順序未定義。
如果你只要獲取到可枚舉屬性,查看 Object.keys 或用 for...in循環(還會獲取到原型鏈上的可枚舉屬性,不過可以使用hasOwnProperty()方法過濾掉)。
// 無法枚舉到原型鏈中的屬性 var obj = Object.create({y:20}); obj.x = 10; console.log( Object.getOwnPropertyNames(obj) ); // "x" // 可以枚舉Enumerable為false的屬性 Object.defineProperty(obj,"z",{ value:"z", enumerable:false }) console.log( Object.getOwnPropertyNames(obj) ); // "x,z" // 對于數組對象(length屬性為不可枚舉) var arr = ["a","b","c"]; console.log( Object.getOwnPropertyNames(arr) ); // "0,1,2,length" // 對于隨機排列的數組對象 var obj_ramdom = {100:"a",2:"b",50:"c"}; console.log( Object.getOwnPropertyNames(obj_ramdom) ); // "2,50,100"詳細:MDN —— Object.getOwnPropertyNames() for-in、Object.keys、Object.getOwnPropertyNames特點區分 三者關于是否受Enumerable的限制測試
var obj = {x:10,y:20}; Object.defineProperty(obj,"z",{ value:30, enumerable:false, }); // for-in for (var a in obj) { console.log(a); // "x,y" } // Object.keys console.log( Object.keys(obj) // "x,y" ); // Object.getOwnPropertyNames() console.log( Object.getOwnPropertyNames(obj) // "x,y,z" );三者關于是否可以枚舉原型鏈的測試
function Test() { this.x = 10; this.y = 20; } Test.prototype.z = 30; // z為原型鏈屬性 var obj = new Test(); // for-in for (var a in obj) { console.log(a) // "x,y,z" } // Object-keys console.log( Object.keys(obj) // "x,y" ) // Object.getOwnPropertyNames() console.log( Object.getOwnPropertyNames(obj) // "x,y" )
我們如何記憶呢?就記最特殊的!
for-in:只有它可以枚舉原型鏈里的屬性,并且它也不是Object對象的方法 Object.getOwnPropertyNames():只有它可以享有Enumerable的"豁免權",不管如何設置只要是這個對象上的自有屬性都可以枚舉到! 對象屬性控制相關方法 四個相關的方法在這里先列出,這里要要提到數據屬性和訪問器屬性《JS高程》—— 數據屬性與訪問器屬性
強薦:阮一峰 —— 屬性描述對象
4. Object.defineProperty()5. Object.getOwnPropertyDescriptor()Object.defineProperty() 方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 并返回這個對象。
6. Object.defineProperties()Object.getOwnPropertyDescriptor() 返回指定對象上一個自有屬性對應的屬性描述符。(自有屬性指的是直接賦予該對象的屬性,不需要從原型鏈上進行查找的屬性)
// 采用Object.defineProperty定義的屬性,如果不顯示定義 // enumerable,configurable,writable值默認為false(與對象字面量相反) var obj = {}; Object.defineProperty(obj,"x",{ value:"obj.x" }); // 使用Object.getOwnPropertyDescriptor()獲取屬性對象 var obj_attr = Object.getOwnPropertyDescriptor(obj,"x"); for (var i in obj_attr) { document.write(i+" : "+obj_attr[i]+"
") } // 默認下數據屬性都是false
Object.defineProperties() 方法直接在一個對象上定義新的屬性或修改現有屬性,并返回該對象。
var obj = {}; Object.defineProperties(obj,{ x:{ value:"obj.x", writable:true, enumerable:true, configurable:true }, y:{ value:"obj.y", writable:true, enumerable:true, configurable:true }, z:{ value:"obj.z" } }) console.log(Object.keys(obj)); // "x,y" z屬性enumerable默認為false // 當然,z屬性的數據屬性都是false沖突:
《JavaScript編程全解》:只要將get屬性與set屬性指定為相應的函數,就能夠定義一個只能夠通過訪問器getter和setter來訪問值的屬性。訪問器與value屬性是互相排斥的,也就是說,如果指定了value屬性的值,訪問器(包括get和set)就會失效;反之,如果指定了訪問器(get或set中的某一個亦或是都存在),value屬性就會失效。
《JS高程3》:不一定非要同時指定getter和setter。只指定getter意味著屬性是不能寫,嘗試寫入屬性會被忽略。在嚴格模式下,嘗試寫入只指定了getter函數的的屬性會拋出錯誤。類似地,沒有指定setter函數的屬性也不能讀,否則在非嚴格模式下會返回undefined,在嚴格模式下會拋出錯誤。
var obj = {_x:10}; // 定義一個訪問器屬性 Object.defineProperty(obj,"x",{ get:function () { return this._x } }) // 讀取obj.x會隱式調用訪問器屬性,返回obj._x的值(下劃線代表此屬性只能通過訪問器讀寫) console.log(obj.x); // 10 // 嘗試為訪問器屬性賦值 // 直接賦值 obj.x = "aaa"; console.log(obj.x); // 10 賦值失敗 // 獲取obj.x的attributes var objxAttr = Object.getOwnPropertyDescriptor(obj,"x"); for (var i in objxAttr) { document.write( i+" | "+objxAttr[i]+"
" ) } // get | function () { return this._x } // set | undefined // enumerable | false // configurable | false // 不可寫的原因是value屬性與訪問器屬性沖突,即(get、set)與value屬性沖突 // 可以通過查看attributes屬性,判斷屬性是否是訪問器屬性還是數據屬性,存在set或者get的是訪問器屬性
具體內容請移步至相關知識點進行更深入學習,這里只介紹方法基礎用法
對象狀態相關方法 Object.preventExtensions()如果一個對象可以添加新的屬性,則這個對象是可擴展的。preventExtensions 可以讓這個對象變的不可擴展,也就是不能再有新的屬性。需要注意的是不可擴展的對象的屬性通常仍然可以被刪除。嘗試給一個不可擴展對象添加新屬性的操作將會失敗,不過可能是靜默失敗,也可能會拋出 TypeError 異常(嚴格模式)。
Object.preventExtensions 只能阻止一個對象不能再添加新的自身屬性,仍然可以為該對象的原型添加屬性。然而Object.preventExtensions會阻止一個對象將__proto__屬性重新指向另一個對象。
// Object.preventExtensions將原對象變的不可擴展,并且返回原對象 var obj = {}; var obj2 = Object.preventExtensions(obj); alert(obj===obj2); // true obj.x = "obj.x"; alert(obj.x); // undefined // 采用對象字面量定義的對象默認可擴展 var o = {}; alert(Object.isExtensible(o)); // true // 當然,通過調用方法可以阻止 Object.preventExtensions(o); alert(Object.isExtensible(o)); // false // 使用Object.defineProperty方法為一個不可擴展的對象添加新屬性會拋出異常. var o2 = {a:"a"}; Object.preventExtensions(o2); Object.defineProperty(o2,"b",{ value:"test" }) // "Uncaught TypeError: Cannot define property:b, object is not extensible." // 一個不可擴展對象的原型是不可更改的,__proto__是個非標準魔法屬性,可以更改一個對象的原型. var b = Object.preventExtensions({x:1,y:2}); b.__proto__ = {a:10,b:20}; // "Uncaught TypeError: #
詳細:MDN —— Object.preventExtensions()
Object.seal()通常情況下,一個對象是可擴展的(可以添加新的屬性)。密封一個對象會讓這個對象變的不能添加新屬性,且所有已有屬性會變的不可配置。屬性不可配置的效果就是屬性變的不可刪除,以及一個數據屬性不能被重新定義成為訪問器屬性,或者反之。但屬性的值仍然可以修改。嘗試刪除一個密封對象的屬性或者將某個密封對象的屬性從數據屬性轉換成訪問器屬性,結果會靜默失敗或拋出TypeError 異常(嚴格模式)。
不會影響從原型鏈上繼承的屬性。但 _proto_ ( ) 屬性的值也會不能修改。
// 默認可以修改屬性,添加屬性 var obj = { a:"a", b:"b" }; // 密封對象Object.seal(),注意方法會返回原對象 obj = Object.seal(obj); console.log(Object.isSealed(obj)); // true // 依然可以修改屬性上的值 obj.a = "Rewrite obj.a"; obj.b = "Rewrite obj.b"; console.log(obj.a+" | "+obj.b); // "Rewrite obj.a | Rewrite obj.b" // 但是除此之外的操作都無法完成 obj.z = "obj.z"; console.log(obj.z); // undefined 新屬性寫入失敗 console.log(delete obj.a); // false 刪除失敗 // 無法定義訪問器屬性 Object.defineProperty(obj,"b",{ // "Uncaught TypeError: Cannot redefine property: b" get:function () { return this.b; } }); // 方法也無法寫入新屬性 Object.defineProperty(obj,"z",{ // 拋出TypeError異常 value:"obj.z" }); console.log(obj.z); // "Uncaught TypeError: Cannot define property:z, object is not extensible."Object.freeze()
Object.freeze() 方法可以凍結一個對象,凍結指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性。也就是說,這個對象永遠是不可變的。該方法返回被凍結的對象。
// 默認可以修改屬性,添加屬性,刪除屬性等操作 var obj = { a:"a", b:"b", o:{} }; // 調用Object.freeze obj = Object.freeze(obj); // 現在任何對對象的操作都會失敗,嚴格模式下會TypeError異常 console.log(delete obj.a); // false obj.z = "obj.z"; console.log(obj.z); // undefined // 但是非凍結對象依然可以修改,對象內數組、對象等引用類型 obj.o.fn = function () {console.log("yes")}; obj.o.fn(); // "yes" 添加成功MDN提供了一個完全凍結對象的函數:
obj = { internal : {} }; Object.freeze(obj); obj.internal.a = "aValue"; obj.internal.a // "aValue" // 想讓一個對象變的完全凍結,凍結所有對象中的對象,我們可以使用下面的函數. function deepFreeze (o) { var prop, propKey; Object.freeze(o); // 首先凍結第一層對象. for (propKey in o) { prop = o[propKey]; if (!o.hasOwnProperty(propKey) || !(typeof prop === "object") || Object.isFrozen(prop)) { // 跳過原型鏈上的屬性和已凍結的對象. continue; } deepFreeze(prop); //遞歸調用. } } obj2 = { internal : {} }; deepFreeze(obj2); obj2.internal.a = "anotherValue"; obj2.internal.a; // undefinedObject.isExtensible()、Object.isSealed()、Object.isFrozen()
為對應的檢測方法:
嚴格程度升序:preventExtensions —— seal —— freeze鏈接:
MDN:Object.isExtensible()
MDN:Object.isSealed()
MDN:Object.isFrozen()
Object.isExtensible():
默認情況下,對象是可擴展的:即可以為他們添加新的屬性。以及它們的 proto 屬性可以被更改。Object.preventExtensions,Object.seal 或 Object.freeze 方法都可以標記一個對象為不可擴展(non-extensible)。
Object.isSealed():
// 新建對象默認不可密封 var obj = {}; console.log(Object.isSealed(obj)); // false // 如果是空對象變為不可擴展preventExtensions,則對象也會變成密封對象 obj = Object.preventExtensions(obj); console.log( Object.isExtensible(obj)+" | " +Object.isSealed(obj) ) // false | true 不可擴展 | 密封 // 但不是空對象,則不會發生上面情況,記?。好芊鈱ο笈cConfigurable屬性相關聯 var obj2 = {x:"obj2.x"}; Object.preventExtensions(obj2); console.log( Object.isExtensible(obj2)+" | " +Object.isSealed(obj2) ) // false | false 不可擴展 | 不密封 // 反過來設置configurable設置為false,則自動變為密封對象 var o = {a:"o.a"}; Object.preventExtensions(o); Object.defineProperty(o,"a",{ configurable:false }); console.log( Object.isSealed(o) ); // true // 直接生成一個密封對象 var obj_seal = {}; Object.seal(obj_seal); // 當然密封對象也可以是凍結對象 Object.isFrozen(obj_seal); // true var o2 = Object.seal({a:"o2.a"}); console.log(Object.isFrozen(o2)); // false 依舊可更改o2.a屬性
Object.isFrozen()
一個對象是凍結的(frozen)是指它不可擴展,所有屬性都是不可配置的(non-configurable),且所有數據屬性(data properties)都是不可寫的(non-writable)
// 一個對象默認是可擴展的,所以它也是非凍結的. assert(Object.isFrozen({}) === false); // 一個不可擴展的空對象同時也是一個凍結對象. var vacuouslyFrozen = Object.preventExtensions({}); assert(Object.isFrozen(vacuouslyFrozen) === true); // 一個非空對象默認也是非凍結的. var oneProp = { p: 42 }; assert(Object.isFrozen(oneProp) === false); // 讓這個對象變的不可擴展,并不意味著這個對象變成了凍結對象, // 因為p屬性仍然是可以配置的(而且可寫的). Object.preventExtensions(oneProp); assert(Object.isFrozen(oneProp) === false); // ...如果刪除了這個屬性,則它會成為一個凍結對象. delete oneProp.p; assert(Object.isFrozen(oneProp) === true); // 一個不可擴展的對象,擁有一個不可寫但可配置的屬性,則它仍然是非凍結的. var nonWritable = { e: "plep" }; Object.preventExtensions(nonWritable); Object.defineProperty(nonWritable, "e", { writable: false }); // 變得不可寫 assert(Object.isFrozen(nonWritable) === false); // 把這個屬性改為不可配置,會讓這個對象成為凍結對象. Object.defineProperty(nonWritable, "e", { configurable: false }); // 變得不可配置 assert(Object.isFrozen(nonWritable) === true); // 一個不可擴展的對象,擁有一個不可配置但可寫的屬性,則它仍然是非凍結的. var nonConfigurable = { release: "the kraken!" }; Object.preventExtensions(nonConfigurable); Object.defineProperty(nonConfigurable, "release", { configurable: false }); assert(Object.isFrozen(nonConfigurable) === false); // 把這個屬性改為不可寫,會讓這個對象成為凍結對象. Object.defineProperty(nonConfigurable, "release", { writable: false }); assert(Object.isFrozen(nonConfigurable) === true); // 一個不可擴展的對象,值擁有一個訪問器屬性,則它仍然是非凍結的. var accessor = { get food() { return "yum"; } }; Object.preventExtensions(accessor); assert(Object.isFrozen(accessor) === false); // ...但把這個屬性改為不可配置,會讓這個對象成為凍結對象. Object.defineProperty(accessor, "food", { configurable: false }); assert(Object.isFrozen(accessor) === true); // 使用Object.freeze是凍結一個對象最方便的方法. var frozen = { 1: 81 }; assert(Object.isFrozen(frozen) === false); Object.freeze(frozen); assert(Object.isFrozen(frozen) === true); // 一個凍結對象也是一個密封對象. assert(Object.isSealed(frozen) === true); // 當然,更是一個不可擴展的對象. assert(Object.isExtensible(frozen) === false);Object.getPrototypeOf()
給定對象的原型。如果沒有繼承屬性,則返回 null 。
var obj = {}; console.log(Object.getPrototypeOf(obj) === Object.prototype); // true var fn = function () {}; console.log(Object.getPrototypeOf(fn) === Function.prototype); // true var arr = []; console.log(Object.getPrototypeOf(arr) === Array.prototype); // true var q = {x:"x"}; var p = Object.create(q); console.log(Object.getPrototypeOf(p) === q); // true // 如果參數不是引用類型,將拋出異常 var num = 123; Object.getPrototypeOf(num); // "Uncaught TypeError: Object.getPrototypeOf called on non-object"Object實例方法 Object.prototype.valueOf()
JavaScript 調用 valueOf() 方法用來把對象轉換成原始類型的值(數值、字符串和布爾值)。 你很少需要自己調用此函數;當遇到一種需要轉換成一個原始值情況時候, JavaScript 會自動調用此函數。
默認情況下, valueOf() 會被每個對象Object繼承。每一個內置對象都會覆蓋這個方法為了返回一個合理的值,如果對象沒有原始值,valueOf() 就會返回對象自身。
你可以在自己的代碼中使用 valueOf 方法用來把內置對象的值轉換成原始值。 當你創建了自定義對象時,你可以覆蓋 Object.prototype.valueOf() 并調用來取代 Object 方法。
JavaScript的許多內置對象都重寫了該函數,以實現更適合自身的功能需要。因此,不同類型對象的valueOf()方法的返回值和返回值類型均可能不同。
// Array:返回數組本身 var arr = [1,2,3,"Array"]; console.log(arr+" | "+(arr.valueOf() === arr)); // "1,2,3,Array | true" // String:返回當前字符串 var str = "string"; console.log(str.valueOf() === str); // true // Number:返回當前值 var num = 123; console.log(num.valueOf() === num); // true // Boolean:返回當前布爾值 var boo = true; // 布爾值 console.log(boo.valueOf() === boo); // true // 這里是布爾對象 var boo2 = new Boolean(false); // 布爾對象 console.log(boo2.valueOf()); // false console.log(typeof boo2.valueOf()); // boolean // 注意:這里對布爾對象操作,返回的是原值的boolean類型,而不在是引用類型 // Date:從1970年1月1日到現在的毫秒數 var date = new Date(); console.log(date.valueOf()); // "1497789410938" // function: 返回當前函數 var fn = function () {console.log("fn")}; (fn.valueOf())(); // fn // Object: 返回對象本身 var obj = {x:"obj.a"}; console.log(obj.valueOf() === obj); // true
當然也可以覆蓋方法:
var obj = {a:1}; obj.valueOf = function () {return this.a} console.log(obj+1); // 2 // 這里隱式調用了valueOf方法Object.prototype.toString()
每個對象都有一個 toString() 方法,當對象被表示為文本值時或者當以期望字符串的方式引用對象時,該方法被自動調用。默認情況下,toString() 方法被每個繼承自Object的對象繼承。如果此方法在自定義對象中未被覆蓋,toString() 返回 "[object type]",其中type是對象類型。
// toString返回對象的字符串形式,默認情況下返回類型字符串 var o1 = new Object(); var o2 = {a:1}; console.log(o1.toString()); console.log(o2.toString()); // "[object Object]" // 當然可以自定義它 var obj = {}; obj.toString = function () {return 1} console.log(2+obj); // 3關于toString()更詳細的可以看這里: 阮一峰 toString()的應用:判斷數據類型 Object.prototype.toLocaleString()
Object.prototype.hasOwnProperty()Object"s toLocaleString 返回調用 toString() 方法的結果。
var num = 123; console.log(num.toString() === num.toLocaleString()); // true var obj = {}; console.log(obj.toString() === obj.toLocaleString()); // true
所有繼承了 Object 的對象都會繼承到 hasOwnProperty 方法。這個方法可以用來檢測一個對象是否含有特定的自身屬性;和 in 運算符不同,該方法會忽略掉那些從原型鏈上繼承到的屬性。
// 判斷屬性書否存在 var obj = {x:"obj.x"}; console.log(obj.hasOwnProperty("x")); // true delete obj.x; console.log(obj.hasOwnProperty("x")); // false // 判斷自身屬性還是繼承屬性 var p = {z:10}; var o = Object.create(p); o.a = 20; console.log(o.hasOwnProperty("a")+" | "+o.hasOwnProperty("z")); // true | false console.log(o.hasOwnProperty("toString")); // false console.log(o.hasOwnProperty("hasOwnProperty")); // false // 遍歷一個對象的自身屬性 var o1 = {z:"o1.z"}; var o2 = Object.create(o1); o2.x = "o2.x"; o2.y = "o2.y"; for (var i in o2) { if (o2.hasOwnProperty(i)) { console.log("自身屬性:"+i+" | "+"value:"+(o2[i])); } else { console.log(i+"不是自身屬性") } } // "自身屬性:x | value:o2.x" // "自身屬性:y | value:o2.y" // "z不是自身屬性"
hasOwnProperty也可以重寫,所以需要注意這一點:
var foo = { hasOwnProperty: function() { return false; }, bar: "Here be dragons" }; foo.hasOwnProperty("bar"); // 始終返回 false // 如果擔心這種情況,可以直接使用原型鏈上真正的 hasOwnProperty 方法 ({}).hasOwnProperty.call(foo, "bar"); // true // 也可以使用 Object 原型上的 hasOwnProperty 屬性 Object.prototype.hasOwnProperty.call(foo, "bar"); // trueObject.prototype.isPrototypeOf()
Object.prototype.propertyIsEnumerable()isPrototypeOf 方法允許你檢查一個對象是否存在于另一個對象的原型鏈上。
function fn1() { this.a = "a"; } function fn2() { this.b = "b"; } fn2.prototype = new fn1(); function fn3() { this.c = "c"; } fn3.prototype = new fn2(); function fn4() { this.d = "d"; } fn4.prototype = new fn3(); var test = new fn4(); console.log( test.hasOwnProperty("a")+ " | "+test.hasOwnProperty("b")+" | "+test.hasOwnProperty("c")+" | "+test.hasOwnProperty("d") ) // "false | false | false | true"
MDN:Object.prototype.propertyIsEnumerable()每個對象都有 propertyIsEnumerable 方法。該方法可以判斷出指定對象里的屬性是否可枚舉,也就是說該屬性是否可以通過 for...in 循環等遍歷到,不過有些屬性雖然可以通過 for...in 循環遍歷到,但因為它們不是自身屬性,而是從原型鏈上繼承的屬性,所以該方法也會返回false。如果對象沒有指定的屬性,該方法返回 false。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83512.html
摘要:目錄導語對象對象小結導語本系列文章將重點講解提供的原生庫標準庫,只要在支持語言的平臺,標準庫中的提供的對象的屬性和方法都能使用對象對象的理解講的標準庫,首先要從對象談起,因為之后的所有對象都可以看做是對象構造出來的因此,對象可以看做是一個構 目錄 導語 1. Object對象 2. Array對象 3. 小結 導語 本系列文章將重點講解JavaScript提供的原生庫——標準庫,只要...
摘要:目錄導語包裝對象的理解三大包裝對象的知識點小結導語包裝對象是為了彌補基本數據類型的非對象特性而產生的,對于基本類型值而言,本來是不存在屬性和方法的,但是我們可以在使用字面量創建字符串時,調用例如的方法,那么其內在原理究竟是什么呢閱讀完本篇文 目錄 導語 1. 包裝對象的理解 2. 三大包裝對象的知識點 3. 小結 導語 包裝對象是為了彌補基本數據類型的非對象特性而產生的,對于基本類型...
摘要:,微軟發布,同時發布了,該語言模仿同年發布的。,公司在瀏覽器對抗中沒落,將提交給國際標準化組織,希望能夠成為國際標準,以此抵抗微軟。同時將標準的設想定名為和兩類。,尤雨溪發布項目。,正式發布,并且更名為。,發布,模塊系統得到廣泛的使用。 前言 作為程序員,技術的落實與鞏固是必要的,因此想到寫個系列,名為 why what or how 每篇文章試圖解釋清楚一個問題。 這次的 why w...
摘要:由于計算機的國際化,組織的標準牽涉到很多其他國家,因此組織決定改名表明其國際性。規范由萬維網聯盟制定。級標準級標準是不存在的,級一般指的是最初支持的。 這篇筆記的內容對應的是《JavaScript高級程序設計(第三版)》中的第一章。 1.ECMA 和 ECMA-262 ECMA 是歐洲計算機制造商協會的縮寫,全程是 European Computer Manufacturers Ass...
摘要:一般我們對這種構造函數命名都會采用,并把它稱呼為類,這不僅是為了跟的理念保持一致,也是因為的內建類也是這種命名。由生成的對象,其是。這是標準的規定。本文的主題是原型系統的變遷,所以并沒有涉及和對原型鏈的影響。 概述 JavaScript 的原型系統是最初就有的語言設計。但隨著 ES 標準的進化和新特性的添加。它也一直在不停進化。這篇文章的目的就是梳理一下早期到 ES5 和現在 ES6,...
閱讀 3070·2023-04-25 16:50
閱讀 904·2021-11-25 09:43
閱讀 3512·2021-09-26 10:11
閱讀 2518·2019-08-26 13:28
閱讀 2531·2019-08-26 13:23
閱讀 2419·2019-08-26 11:53
閱讀 3566·2019-08-23 18:19
閱讀 2987·2019-08-23 16:27