在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