在判斷一個數據的類型時,能夠使用 Object 原生的 toString 方法bash
咱們先看看下面的例子:app
const str = 'hello world'; str.toString(); // "hello world" Object.prototype.toString(str); // "[object Object]" Object.prototype.toString.call(str); // "[object String]"
由於 str 是字符串,根據原型鏈會調用 String.prototype.toString 方法,函數
# 重寫 String 原型方法 String.prototype.toString = function toString(str) { return 'HHHHHH'; } str.toString(); // "HHHHHH"
toString()是在以特殊的字符串形式輸出 this 的類型
根據 JS 原型鏈,String 對象繼承自 Object 原型 ,即:
String.prototype.__proto__ === Object.prototype; // truethis
String 原型重寫了 toString 方法prototype
# 刪除 String 原型 string 方法 delete String.prototype.toString; str.toString(); // "[object String]" str.toString === Object.prototype.toString; // true
調用問題,使用 call、apply 或者 bind 綁定當前對象指針
Object.prototype.toString(str); // "[object Object]" # 實際上等於: Object.prototype.toString(); // 輸出的是 Object 類型 # 使用bind、apply、bind改變this指向 Object.prototype.toString.call(str); // "[object String]" Object.prototype.toString.apply(str); // "[object String]" Object.prototype.toString.bind(str)(); // "[object String]"
JS 原型鏈有兩個比較重要的屬性:__proto__ 和 prototype;code
構造函數也是對象,也有 __proto__,也會指向其構造函數的原型對象 prototype......一環扣着一環這就是 JS 的原型鏈和繼承原理對象
但原型鏈有一個終點,即:Object.prototype.__proto__ === null;當咱們訪問一個屬性值的時候, 它會沿着原型鏈向上查找, 直到原型鏈終點:null.繼承
注意繼承的是構造函數的 prototype原型鏈
Object.a = 1; Object.prototype.b = 2; const obj = new Object(); obj.a; # undefined obj.b; # 2 Object.a; # 1
個人理解:
Object 和 Object.prototype 是兩種東西,前者是構造函數,後者是原型對象
# 控制檯打印一下 Object; // ƒ Object() { [native code] } # 構造函數 Object.prototype; // 原型對象 # 控制檯將打印出一大坨屬性
Function 是一個構造函數,用於建立其餘函數,包括 Object、Array、RegExp 等構造函數,實際上都是 Function 建立出來得。
# 控制檯打印一下 Function.prototype === Object.__proto__; // true Function.prototype === Array.__proto__; // true Function.prototype === RegExp.__proto__; // true
看到這裏,相信下面的原型鏈你也可以理解了
const test = {}; test.__proto__ === Object.prototype; // true test.__proto__.__proto__ === Object.prototype.__proto__; // true # 指向null Object.__proto__ === Function.prototype; // true Object.__proto__.__proto__ === Object.prototype; // true Object.__proto__.__proto__.__proto__ === null; // true