javascript中的原生函式

笑口常開發表於2017-10-12

  1. 通過建構函式(如 new String(“abc”))建立出來的是封裝了基本型別值(如 “abc”)的封裝物件。
        var a = new String('abc');
        typeof a; // 'object'
        a instanceof String; // true
        Object.prototype.toString.call(a); // [object String]
    
  2. 所有typeof返回值為’object’的物件(如陣列)都包含一個內部屬性 Class這個屬性無法直接訪問,一般通過 Object.prototype.toString(..) 來檢視
    而且多數情況下, 物件內部的[[class]]屬性和建立該物件的內建原生建構函式相對應, 但並非總是如此
    // 對應的情況
        Object.prototype.toString.call([1, 2, 3]); // '[object Array]'
        Object.prototype.toString.call(/regex-literal/i); // '[object RegExp]'
    // 例外情況, undefined和null的原生建構函式並不存在
        Object.prototype.toString.call(undefined); // '[object Undefined]'
        Object.prototype.toString.call(null); // '[object Null]'
    // 對其他基本型別的值的情況, 則會返回其包裝物件
        Object.prototype.toString.call('abc'); // '[object String]'
        Object.prototype.toString.call(42); // '[object Number]'
        Object.prototype.toString.call(true); // '[object Boolean]'
    

封裝物件包裝

  1. 應該儘量使用基本型別
  2. 可以使用Object函式來自行封裝基本型別值
    var a = 'abc';
    var b = Object(a);

    b instanceof String; // true

拆封

1. 使用valueOf()函式得到拆封物件中的基本值
    var a = new String('abc');

    a.valueOf(); // 'abc'
2. 在需要得到封裝物件的基本型別值的地方會發生隱式拆封
    var a = new String('abc');
    var b = a + '';

    typeof a; //'object';
    typeof b; // 'string'

原生函式作為建構函式

  1. Array()

    1. 建構函式 Array(..) 不要求必須帶 new 關鍵字。不帶時,它會被自動補上。因此 Array(1,2,3) 和 new Array(1,2,3) 的效果是一樣的。
    2. 只有一個引數時,會將該引數作為建立陣列的預設長度,這樣建立出來的會是一個空陣列(真的是空的,就類似於delete之後的值),只不過其length屬性被設定為了特定的值,
          var a = new Array(3);
          var b = [undefined, undefined, undefined];
          var c = [];
          c.length = 3;
      
          a; // [empty × 3]
          b; // [undefined, undefined, undefined]
          c; // [empty × 3]
      
      
    3. 從 ES5 規範開始就允許在列表(陣列值、屬性列表等)末尾多加一個逗號(在實際處理中會被忽略不計)。所以如果你在程式碼或者除錯控制檯中輸入 [ , , , ],實際得到的是 [ , , ](包含三個空單元的陣列)
          var ad = [, , , ,];
          ad.length; // 4, 不是5
      
    4. 通過如下方式建立undefined單元的陣列

    Array.apply(null, {length: 3}); // [undefined, undefined, undefined], 可以理解為apply內部有一個for迴圈, 從0開始迴圈到length,以從中取值, 假設apply內部的陣列是arr, 那麼就是從中取arr[0], arr[1], arr[2], 都是undefined

  2. Object(), Function(), RegExp()

    1. 儘量不要使用這3個函式作為建構函式
      1. 使用物件常量語法建立物件可以更加方便的新增屬性
      2. Funtion(),當需要動態定義函式引數和函式體時使用Function()作為建構函式
      3. 正則儘量也使用常量語法, 因為js引擎會在程式碼執行前對其進行預編譯和快取, 但RegExp()在需要動態構建正規表示式時也是很有用的,eg:
            var name = 'Kyle';
            var namePattern = new RegExp('\\b(?:)' + name + ') + \\b', 'ig');
            var matches = someText.match(namePattern);
        
  3. Date()和Error()
    • Date()
      1. 建立日期物件必須使用new Date(), Date()可以帶引數,用來指定日期和時間,不帶引數使用獲取的是當前的日期和時間
      2. Date()主要用來獲取當前的Unix時間戳,(從1970年1月1日,以秒為單位),該值可以通過日期物件中的getTime()來獲得
      3. 從ES5開始,可以使用靜態函式Date.now()獲取這個值
    • Error()
      1. 與前面的Array()類似,可以不帶new關鍵字
      2. 建立錯誤物件主要是為了獲取當前執行棧的上下文
      3. 除了Error()之外,還有一些針對特定錯誤型別的原生建構函式,如EvalError(), RangeError(), ReferenceError(), SyntaxError(), TypeError(), URIError()等,這些建構函式很少直接使用, 只是在程式發生異常時自動呼叫
  4. Symbol()
    符號是具有唯一性的特殊值(並非絕對),用它來命名物件屬性不容易導致重名

        var mysym = Symbol('my own symbol');
        mysys; // Symbol(my own symbol)
        mysys.toString(); // "Symbol(my own symbol)"
        typeof mysys; // 'symbol'
    

    雖然符號實際上並非私有屬性(通過 Object.getOwnPropertySymbols(..) 便可以公開獲得物件中的所有符號),但它卻主要用於私有或特殊屬性。很多開發人員喜歡用它來替代有下劃線(_)字首的屬性,而下劃線字首通常用於命名私有或特殊屬性

原生原型

建構函式的原型包含它們各自型別所特有的行為特徵,但是有些原型比較特殊:
Function的原型是一個函式,正規表示式的原型是一個空正規表示式, 陣列的原型是一個陣列

    typeof Function.prototype; // 'function'
    typeof RegExp.prototype; // '"/(?:)/"——空正規表示式'
    "abc".match( RegExp.prototype );    // [""]
Array.isArray(Array.prototype); // true

相關文章