首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JavaScript `prototype` 設為 `null` 後實例仍可呼叫 `toString` 的原理解析

     編輯:程式設計綜合問答

程式碼

function MyClass() {}
MyClass.prototype = null;
var myClass = new MyClass();
alert(myClass.toString()); // 彈出 "[object Object]"

核心觀念

  1. `prototype` 屬性:函數物件的屬性,決定 `new Fn()` 建立的實例的 `[[Prototype]]` (即 `__proto__`)。
  2. 設為 `null`:實例的 `[[Prototype]]` 變為 `null`,原型鏈終止,**不繼承 `Object.prototype`**。
  3. 但 `toString` 呼叫不報錯:因為 `myClass` 本身是物件,JavaScript 規範定義 **`Object.prototype.toString` 為內建方法**,但若原型鏈無 `toString`,引擎會回退至 **`Object.prototype.toString`**?實際上:

**ES5+ 規範**:若物件的 `[[Prototype]]` 為 `null`,該物件**不繼承任何內建方法**。但 `myClass.toString()` 仍能執行,是因為 **`toString` 是 `Object.prototype` 的方法,而 `myClass` 仍是 `Object` 的實例?**

實際行為驗證 (Chrome/V8)

function MyClass() {}
MyClass.prototype = null;
var o = new MyClass();
console.log(Object.getPrototypeOf(o)); // null
console.log(o.toString()); // "[object Object]"  <-- 為何?
console.log(o.hasOwnProperty('toString')); // false
console.log('toString' in o); // true

真相:`Object.prototype.toString` 被作為 **內建預設** 兜底

當物件無自身 `toString` 且原型鏈為 `null` 時,JavaScript 引擎(V8、SpiderMonkey、JavaScriptCore)為相容性,**內部仍會呼叫 `Object.prototype.toString.call(this)`** 作為預設行為。這屬於實作細節,非標準保證。

標準建議

**不要依賴此行為**。若需確保物件無 `toString`,請顯式定義:

MyClass.prototype = { toString: null }; // 或 Object.create(null) 並自行定義方法
// 或
Object.defineProperty(o, 'toString', { value: undefined, configurable: true });

總結

  • `prototype = null` 切斷原型鏈,實例不再繼承 `Object.prototype` 方法。
  • 但引擎為相容性對 `toString`/`valueOf` 提供內建兜底,導致仍可呼叫。
  • 嚴謹代碼應明確定義或刪除不需的方法。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved