iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 7
0
自我挑戰組

你為什麼不問問神奇 JavaScript 呢?系列 第 7

Day7 - Native 適合用來做建構器嗎?

這部分會出現比較多重複的詞。最後就把他列成表格了。

這章節的主要重點

  • 確認個別的 Native 是否適合或一定要作建構器。
  • 雖然不適合,但有哪些部分適合借用 Native 的。
  • 有哪些不能用 New 關鍵字呢?

作為建構器的 Natives

array、object、function 及正規表達式,最廣為接受是用字面值。

但萬一還是要當成建構器,也是因為他們會帶入你不想處理的例外和陷阱。

解釋所有 Natives 是否適合作為建構器

Array(..)

var a = new Array( 1, 2, 3 ); // 建構器
var b = [1, 2, 3];            // 字面值

建構器有個特殊使用方式。

如果只有一個 number 引數被傳入,那麼此建構器不會把該值當作陣列的內容,而是當作預設的陣列大小。

var a = new Array(3);
a.length; // 3

(這邊指出預先劃分矩陣大小是不需要的。以往寫 matlab 有預先切出矩陣大小。當初的理由是給記憶體畫出可用的空間,現在回頭看,硬體超前,似乎不再需要這樣的功能。)

除此之外,a 在 chrome 的表示法,作者不滿意。因為出現的是 [ undefined x 3 ] 而不是 [ undefined, undefined, undefined ]。

a 在 firefox 裡的表示法是 [ <3 empty slots> ]。

var a = new Array(3);
var b = [undefined, undefined, undefined]

a.join( "-" ); // "--"
b.join( "-" ); // "--"

a.map(function(v,i){return i;}); // [ undefined x 3 ]
b.map(function(v,i){return i;}); // [ 0, 1, 2 ]


(其實這邊請直接理解為,他幫你空出的位置,什麼都沒有,是 empty。 之所以顯示為 undefined 是因為要讓你看見。這樣的值,當然不會進入 map 的迴圈)


那如果我要用 a 建構器做出 b 的樣子呢?

.apply()

var a = Array.apply( null, { length: 3 } );
a; // [undefined, undefined, undefined];

.apply() 是所有的函數可用。他會把值,坎入你呼叫的函數。

:::danger

最底線:不管在任合情況下,永遠不要刻意建立空插槽陣列。
:::

Object(..)、Function(..) 與 RegExp(..)

這些建構器通常都是非必需的。(下面列出通用的方法。)

var c = new Object();
c.foo = "bar";

var d = { foo: "bar" }; // 與 c 等價

var e = new Function( "a", "return a * 2;");
var f = Function(a) {return a * 2 }
function g(a) { return a * 2; }
// 以上三個等價

var h = new RegExp( "^a*b+", "g");
var i = /^a*b+/g;

RegExp() 應該優先選用字面值,效能問題。

JS 引擎會在程式碼執行前預先編譯 ( precompiles )並快取( catch )他們。

但下面的情境常在程式中出現,“動態的為一個正規表達式定義範式”

var name = "Kyle";
var namePattern = new RegExp( "\\b(?:" + name + ")+\\b", "ig" );
var matches = someText.match( namePattern );

Date(..) 與 Error(..)

他們沒有字面值形式。所以當建構器不錯。

建立日期 ( Date ) 物件值,必須用 new Date()。
如果不用 new,會得到特定形式的字串。

如何取得日期的兩個方法

  • 物件實體上呼叫 getTime()
  • Date.now(); (ES5 之前的需要用 polyfill)

建立錯誤 ( error ) 物件,不管有沒有用 new 關鍵字,行為都相同。
(怎麼用 error 物件,請各位客官看書。主要是用來在已知錯誤中抓蟲)

Symbol(..)

()

原生的原型 ( Native Prototypes )

內建的原生建構器,都有自己的 .prototype 物件:Array.prototype、String.prototype。

文件慣例! String.prototype.XYZ 會縮寫成 String#XYZ。

許多方法不會就地 ( in place ) 修改字串,修改動作其實是從現有的值建立一個新的。

Function.prototype 是 function。
Array.prototype 是 array。
RegExp.prototype 是 regrular expression。

(下面牽涉到 prototype,Tony 斷片的很嚴重,到 “this與物件原型” 再看吧!)

總整理

Native 基本型別 字面值 建構子 補充
String() o o x 不用包兩層
Number() o o x 同上
Boolean() o o x 同上
Array() o xx 別建空插槽陣列
Function() xxx 只有動態定義函數參數及本體
Object() o o xxx 沒情境用
RegExp() o o 字面值優先,有動態定範式再用
Date() x oo
Error() x oo 有沒有 new 都一樣
Symbol() o o 不能加 new

參考資料

你所不知道的 JS


上一篇
Day6 - Native
下一篇
Day8 - 強制轉型
系列文
你為什麼不問問神奇 JavaScript 呢?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言