Native prototypes

Object.prototype

// obj = {} 等於 obj = new Object(),Object 是內建建構函式
let obj = {};
alert( obj ); // "[object Object]" ?

// check
let obj = {};
alert(obj.__proto__ === Object.prototype); // true
// obj.toString === obj.__proto__.toString == Object.prototype.toString

alert(Object.prototype.__proto__); // null

Other built-in prototypes

// check
let arr = [1, 2, 3];

// it inherits from Array.prototype?
alert( arr.__proto__ === Array.prototype ); // true

// then from Object.prototype?
alert( arr.__proto__.__proto__ === Object.prototype ); // true

// and null on the top.
alert( arr.__proto__.__proto__.__proto__ ); // null

// 一些方法在原型函式重疊
let arr = [1, 2, 3]
alert(arr); // 1,2,3 <-- the result of Array.prototype.toString

function f() {}

alert(f.__proto__ == Function.prototype); // true
alert(f.__proto__.__proto__ == Object.prototype); // true, inherit from objects

Primitives

string、number、boolean 本身不是物件,但在使用他們的屬性時,內建的建構函式 String、Number、Boolean 會暫時創造包裝物件提供方法。null、undefined 沒有包裝物件,也就是沒有屬性或方法。

Changing native prototypes

// 原型物件可以添加或更改屬性,但不是好主意,因為他是全域物件,會造成衝突
String.prototype.show = function() {
  alert(this);
};

"BOOM!".show(); // BOOM!

// 當我們在做 polyfills 時,允許這樣做,因為舊版引擎還沒支持新功能,要手動加上
if (!String.prototype.repeat) { // if there's no such method
  // add it to the prototype

  String.prototype.repeat = function(n) {
    // repeat the string n times

    // actually, the code should be a little bit more complex than that
    // (the full algorithm is in the specification)
    // but even an imperfect polyfill is often considered good enough
    return new Array(n + 1).join(this);
  };
}

alert( "La".repeat(3) ); // LaLaLa

Borrowing from prototypes

// 在 call/apply 曾借用原型的方法
function showArgs() {
  // 从数组借用 join 方法并在 arguments 的上下文中调用
  alert( [].join.call(arguments, " - ") );
}

showArgs("John", "Pete", "Alice"); // John - Pete - Alice

// 可以這樣寫
function showArgs() {
  alert( Array.prototype.join.call(arguments, " - ") );
}

// 或直接變成物件方法
let obj = {
  0: "Hello",
  1: "world!",
  length: 2,
};

obj.join = Array.prototype.join;

alert( obj.join(',') ); // Hello,world!

Last updated