給數組增加屬性和方法(prototype)

案例分析

var obj = {
  count: 1
}

var myArray = ['red', 'white', 'black'];
console.log(myArray.length);

myArray.obj = obj;
console.log(myArray.length);

兩次打印myArray的length是多少?為什么?


理想與現實的沖突

我認為結果應該是 3 4

但結果是 4 4

打印的數組如我所想 [ 'red', 'white', 'black', obj: { count: 1 } ]

然length 仍然為3

老實說,一上來就被整懵逼了。

從現實出發


可仔細一看,案例本來就沒有給數組多增加元素個數。

myArray.obj = obj;

這一點非常關鍵 案例用的時 點語法 賦值操作,那么意思就是給myarray數組增加了一個obj屬性。屬性值是定義的obj對象。

而真正的向數組添加元素 用的是數組的 push方法。push才是真正的向數組中添加一個元素。

如果代碼改成這樣,數組長度就是理想的長度了。

myArray.push(obj);
console.log(myArray);
console.log(myArray.length);

而.obj只是為當前的這個數組增加屬性,

myArray.name = 'xiaoming';
console.log(myArray);
console.log(myArray.length);

實驗表明,使用.屬性只能增加數組的屬性,

而這些屬性和值通常通過鍵值對的形式放在數組元素的后面,而不會增加數組的個數。

[ 'red', 'white', 'black', obj: { count: 1 } ]

對數組長度的理解


數組長度:

The length property of an object which is an instance of type Array sets or returns the number of elements in that array. The value is an unsigned, 32-bit integer that is always numerically reater than the highest index in the array.

  1. length 屬性 是數組設置或返回數組中的元素個數。它的值是無符號32位整數,始終數值上大于數組中的最高索引。
var fruits = [];
fruits.push('banana', 'apple', 'peach');
console.log(fruits.length); // 3
// 當給數組設置一個屬性,當這個屬性是合法的數組索引,并且數組索引超出了當前數組的邊界,引擎就會相應的更新數組的length屬性
fruits[5] = 'mango';
console.log(fruits[5]); // 'mango'
console.log(Object.keys(fruits));  // ['0', '1', '2', '5']
console.log(fruits.length); // 6

  1. 由于length可以取值也可以賦值,所以length屬性并不能確切的表示數組中元素的個數,解釋如下:

You can set the length property to truncate an array at any time. When you extend an array by changing its length property, the number of actual elements does not increase; for example, if you set length to 3 when it is currently 2, the array still contains only 2 elements. Thus, the length property does not necessarily indicate the number of defined values in the array. See also Relationship between length and numerical properties.

你可以隨時設置length屬性來縮短一個數組,它真的就縮小的,只會保留length個元素。
當你通過改變length屬性擴大數組時,實際的元素個數并沒有增加,例如,當前數組有2個元素,把length設置為3,數組依然只包含2個元素。因此 length屬性不能確切的反映數組中的元素個數。

  1. length和數字屬性的關系
    我們知道數組是通過索引訪問的 或者說 通過下標來訪問的。那么下標其實就是數字屬性,而數組的length屬性是和數字屬性連在一起的。
    其中數組幾個內置的函數(比如, join, slice, indexOf, 等) 被調用時會計算數組的length屬性,
    其他的方法(比如, push, splice, 等)也會更新數組的length屬性

  2. 既然屬性可以用點語法訪問,為什么數字屬性不行
    屬性一般可以通過點語法訪問,這要求點語法點到的必須是一個合法命名的變量。而合法的命名是不允許以數字開頭的。
    所以這個屬性只能通過括號表示法方法 即myArray[0]

  1. 關于數組中有多少個元素的思考
    通過上述分析,我們知道length屬性并不能正確表示數組中有多少個元素。
    比如說修改數組的最高索引,或者更直接點直接修改length屬性的值,這樣都無法反應數組到底有幾個元素。
    這就有個問題,如何知道數組中到底有多少個元素?
    上面打印結果的 obj:{count:1}是不是數組的元素呢?應不應該算上?
    數組的屬性是數字,通過索引訪問。數組的索引就是數組特殊的屬性名,而obj不是數字屬性 以這種形式展示在數組中 obj:{count:1} 那么數組本質上或許也是這么寫的[0:'red',1:'white']
    那么我個人覺得要算上,數組中鍵的個數就代表了數組中有多少個元素
    console.log(Object.keys(myArray).length);
    然而這么算就會有一個困惑。還好這個屬性是添加在具體的數組中的,所以才有顯示出來,如果是在Array.prototype中定義的,那么就不會打印出來。所以我覺得非數字類索引是不需要的算入有多少個元素的。
    如果要算有多少個元素,就要排除到這些非數字屬性。

總結與應用


如果看到鍵值對的形式(外面沒有括號包裹,即非獨立對象)出現在數組中,

那它就不是作為數組元素存在的,而是作為數組的屬性或方法存在的。

這就意味著 可以給數組增加 屬性和方法 方便我們使用了。

比如返回每個數組的平方

var myArray = [1,2,3,4,5];
myArray.square = function () {
    for (var i = this.length - 1; i >= 0; i--) {
        this[i] *= this[i];
    }
    return this;
};
console.log(myArray.square());

加深理解


我查了查,這個東西其實叫做原型prototype其作用就是給對象添加屬性和方法的。上述鏈接是W3C的參考例子。是從具體的對象層面增加的屬性和方法。案例也是這個意思。

還可以給每一個對象增加屬性和方法,這是MDN對Array.prototype的解釋,比如給Array增加一個first方法,那么所有的數組實例都擁有這個方法,而且打印數組時,此方法在數組中不會看到。

console.log(myArray.square());
if (!Array.prototype.first) {
  Array.prototype.first = function() {
    return this[0];
  }
}
console.log(myArray.first());

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容

  • Javascript有很多數組的方法,有的人有W3C的API,還可以去MDN上去找,但是我覺得API上說的不全,M...
    頑皮的雪狐七七閱讀 4,143評論 0 6
  • 一、JS前言 (1)認識JS 也許你已經了解HTML標記(也稱為結構),知道了CSS樣式(也稱為表示),會使用HT...
    凜0_0閱讀 2,788評論 0 8
  • 第1章 認識JS JavaScript能做什么?1.增強頁面動態效果(如:下拉菜單、圖片輪播、信息滾動等)2.實現...
    mo默22閱讀 1,317評論 0 5
  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,762評論 0 33
  • FreeCodeCamp - Basic JavaScript 寫在前面: 我曾經在進谷前刷過這一套題,不過當時只...
    付林恒閱讀 16,474評論 5 28