在javascript建立的基礎底層,都會透過 prototype (原型鍊) 來設計出許多預設功能

原則上,不建議透過prototype來修改或打造新的功能

但是透過修改prototype的方式來練習,優點是可以直接來了解底層運作原理

這裡會針對幾個方向來對 prototype 特性來作探討及練習

對於詳細的設計構思,則推薦從下面這兩篇開始

Javascript繼承機制的設計思想 從設計初衷解釋 JavaScript 原型鏈

除此外,在底層知識方面,還有一些特性深入了解之後,也能幫助你更了解 prototype

prototype, __proto__, constructor
Object.prototype, Function.prototype, new

function 與 new instance

在開始前,先了解一般 function 與 new instance 型態

首先,我們先透過 typeof 檢查 function 的類型,輸出為 function

function myfn(){ }
console.log(myfn.__proto__); //function(){}
console.log(typeof(myfn));//function

將 function 透過 new instance 之後,再來檢查型態,則為 Object

function myfn(){ }
var new_myfn  = new myfn();
console.log(new_myfn.__proto__);//Object {}
console.log(typeof(new_myfn));//Object

function

function 被呼叫時,本身會建立一個scope以及 closure 環境,

並且包含this,會指向呼叫函式的物件(通常都是 windows)

(可以透過 bind, call, apply 來將定義this)

constructor

所有JavaScript中的函式都有一個內建的prototype屬性,指向一個特殊的(prototype物件)物件,物件的contructor屬性,指向原來的函式

從下方範例,可以得知 myfn == myfn.prototype.constructor

function myfn(t){
  console.log(t)
}

//myfn.prototype.constructor 等同於  myfn 本身
var myFunction = myfn.prototype.constructor;
myFunction('hello');

new

當我們建立一個function之後,就能使用new instance 來實體化

透過 new 建立物件實體的 proto 會指向原來的 function 的 prototype

因此,就能透過下面的方式來變更或修改function的prototype

//myfn
function myfn(){
    this.username='adam';
}
//修改 myfn 的 prototype
myfn.prototype = {
  title: 'hello world',
  tel: '1234567'
}

//new myfn 以及輸出值
var myFunction = new myfn();
console.log(myFunction.title);
console.log(myFunction.tel);
console.log(myFunction.username);

因此,從上面可以了解到

如果我們沒有需要額外新增屬性、方法的話,就直接使用function的形式即可 如果有,就可以透過 new instance 的方式來改寫原始 function 的 prototype 屬性

Array

陣列本身即是一個物件的屬性

var myary = Array();

console.log(typeof(myary));//Object

因此,就能直接的方式來修改或變更陣列的prototype

在javascript 陣列,已經有設計出許多屬性,以及透過prototype設計出許多可以直接用的方法 關於 Array 預設的功能,可以查看這裡

例如

var numbers = [1, 2, 3];
numbers.push(4);
console.log(numbers.length);//4
console.log(numbers);//[1,2,3,4]

當然,我們也可以自己透過修改或新增prototype的方式,來建立新的陣列功能 (原則上,不建議透過prototype來修改或打造新的功能)

例如,這裡製作一個 find_last 功能: 找到陣列最後一個值

Array.prototype.find_last = function () {
    return this[this.length - 1];
};

就能直接用來取得最後一個值

var numbers = [1,2,3,4,5];
console.log(numbers.find_last()) // 5