原型笔记
- 1. Object.getOwnPropertyNames()
在學(xué)習(xí)使用該方法的時(shí)候,查閱了《JavaScript高級(jí)程序設(shè)計(jì)》與 MDN 來綜合學(xué)習(xí)。
先來看看MDN對(duì)其的表述:
參數(shù)
- 一個(gè)對(duì)象,其自身的可枚舉和不可枚舉屬性的名稱被返回。
obj:返回值
? 在給定對(duì)象上找到的屬性對(duì)應(yīng)的字符串?dāng)?shù)組。
? 描述
Object.getOwnPropertyNames()?返回一個(gè)數(shù)組,該數(shù)組對(duì)元素是?obj自身擁有的枚舉或不可枚舉屬性名稱字符串。?數(shù)組中枚舉屬性的順序與通過?for...in?循環(huán)(或?Object.keys)迭代該對(duì)象屬性時(shí)一致。數(shù)組中不可枚舉屬性的順序未定義。
同時(shí),舉出了幾個(gè)例子來表顯示,例如:
var arr = ["a", "b", "c"]; console.log(Object.getOwnPropertyNames(arr).sort()); // ["0", "1", "2", "length"]// 類數(shù)組對(duì)象 var obj = { 0: "a", 1: "b", 2: "c"}; console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]// 使用Array.forEach輸出屬性名和屬性值 Object.getOwnPropertyNames(obj).forEach(function(val, idx, array) {console.log(val + " -> " + obj[val]); }); // 輸出 // 0 -> a // 1 -> b // 2 -> c//不可枚舉屬性 var my_obj = Object.create({}, {getFoo: {value: function() { return this.foo; },enumerable: false} }); my_obj.foo = 1;console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]
正如:MDN上所述,該方法返回的是對(duì)象自身的可枚舉與不可枚舉屬性,即返回的是一個(gè)數(shù)組。并且在查閱《JavaScript高級(jí)程序設(shè)計(jì)》這本書籍的時(shí)候,卻發(fā)現(xiàn)了一個(gè)問題。
function Person(){}
Person.prototype.name = 'asfd'
Person.prototype.age = 15
Person.prototype.sayName = function () {
console.log(this.name)
}
var keys = Object.getOwnPropertyNames(Person.prototype) console.log(keys)
// 書籍中表述keys返回的是 ['constructor', 'name', 'age', 'sayName']
// 但是當(dāng)將Person.property設(shè)置一個(gè)以對(duì)象字面量形式創(chuàng)建的對(duì)象時(shí),就不再返回constructor. 書籍中已經(jīng)解釋此時(shí)的constructor不再指向Person // 于是,我真的操作了一遍才發(fā)現(xiàn),真的如此
// 實(shí)例如下:
function Person(){ } Person.prototype = {name: 'zwj',age: 21,say: function () {console.log('say')} }
var keys = Object.getOwnPropertyNames(Person.property)
console.log(keys)
// 此時(shí)返回的 ['name','age','sayName']
我根據(jù)書中理解如下:設(shè)置一個(gè)以對(duì)象字面量形式創(chuàng)建的對(duì)象,雖然結(jié)果相同,但是constructor不再指向Person,這就涉及到原型鏈了
首先,每個(gè)構(gòu)造函數(shù)被創(chuàng)建的時(shí)候,同時(shí)就創(chuàng)建了一個(gè)構(gòu)造函數(shù)對(duì)應(yīng)的原型對(duì)象,即: 構(gòu)造函數(shù).prototype?
這個(gè)對(duì)象就會(huì)自動(dòng)獲得一個(gè)constructor屬性,這個(gè)屬性就是該對(duì)象指向構(gòu)造函數(shù)的指針,你也可以試試輸出: Person.prototype? ? Person.prototype.constructor? ? ?Person.prototype.constructor.prototype 等等,就會(huì)發(fā)現(xiàn)形成了一個(gè)閉環(huán)...
這里我們使用的語法去接收屬性值,本質(zhì)上默寫了prototype對(duì)象,這時(shí)候,改寫的對(duì)象默認(rèn)的constructor指向?yàn)镺bject構(gòu)造函數(shù),畢竟函數(shù)也是對(duì)象,在JS中一切皆為對(duì)象...
所以如果我們通常為了在原型上進(jìn)行大量的屬性寫入,就必須對(duì)這部分操作進(jìn)行注意,需要在使用設(shè)置對(duì)象字面量方式之后手動(dòng)為其添加constructor屬性的指向,這樣做的目的就是為了確保通過該屬性能夠訪問到適當(dāng)?shù)闹?..
當(dāng)然你會(huì)覺得這樣設(shè)置并不是完美,畢竟對(duì)于constructor這個(gè)屬性,他應(yīng)該是不可枚舉的,此時(shí),卻是可枚舉的,這是就需要我們使用Object.defineProperty()進(jìn)行相應(yīng)的設(shè)置.相應(yīng)的代碼如下:
function Person(){ } // 此時(shí)重寫了prototype對(duì)象 constructor指向Object Person.prototype = {name: 'Nick',age: 15,sayName: function(){consolelog(this.name)} } // 對(duì)constructor進(jìn)行設(shè)置修改 Object.defineProperty(Person.prototype, 'constructor', {enumerable: false, // 設(shè)置是否可枚舉 false為不可枚舉value: Person // 設(shè)置值為Person }) //可以通過definePrototype進(jìn)行更改數(shù)據(jù)屬性的共有6個(gè),其余4個(gè)分別為: // configurable ----------> 表示是否可以通過delete進(jìn)行刪除 默認(rèn)為true // writable ----------> 表示是否可以修改屬性的值 默認(rèn)為true
// get ----------> 一個(gè)給屬性提供 getter 的方法,如果沒有 getter 則為 undefined。該方法返回值被用作屬性值。默認(rèn)為 undefined。
// set --------> 一個(gè)給屬性提供 setter 的方法,如果沒有 setter 則為 undefined。該方法將接受唯一參數(shù),并將該參數(shù)的新值分配給該屬性。默認(rèn)為 undefined。
總結(jié): 在進(jìn)行創(chuàng)建構(gòu)造函數(shù)的時(shí)候,以前習(xí)慣只是將constructor直接寫在重寫的prototype對(duì)象中,但是卻忽略了其中最重要的一條信息,那就是constructor屬性本身是不可枚舉的屬性,還需要更深一層的操作去設(shè)置constructor.看問題不能只看表面,更應(yīng)該注重于內(nèi)在...
?
轉(zhuǎn)載于:https://www.cnblogs.com/gxlself/p/9121090.html
總結(jié)
- 上一篇: 同意好友
- 下一篇: 中国顶级黑客45秒使用声音来破坏您的计算