JS原型與繼承的祕密瀏覽器
1、protoapp
除null和undefined,JS中的全部數據類型都有這個屬性; 它表示當咱們訪問一個對象的某個屬性時,若是該對象自身不存在該屬性, 就從它的__proto__屬性上繼續查找,以此類推,直到找到,若找到最後仍是沒有找到,則結果爲undefined函數
咱們把一個對象的__proto__屬性所指向的對象叫該對象的原型;咱們能夠修改一個對象的原型來讓這個對象擁有某種屬性或某個方法性能
// 修改一個Number類型的值的原型spa
const num = 1;prototype
num.__proto__.name = "My name is 1";code
console.log(num.name); // My name is 1對象
// 修改一個對象的原型繼承
const obj = {};ip
obj.__proto__.name = "dreamapple";
console.log(obj.name); // dreamapple
需注意的是,__proto__屬性雖多數瀏覽器支持,但其實它僅在ECMAScript 2015規範中才被準肯定義, 目的是爲了給這個傳統的功能定製一個標準,以確保瀏覽器間的兼容性。經過使用__proto__屬性來修改一個對象的原型很是慢且影響性能。 因此,若想獲取一個對象的原型,推薦用Object.getPrototypeOf 或Reflect.getPrototypeOf,設置一個對象的原型推薦用Object.setPrototypeOf或Reflect.setPrototypeOf
2、prototype
首先要記住的是,該屬性通常只存在於函數對象上; 只要是能做爲構造器的函數,都包含這個屬性。即只要這個函數能經過new生成一個新對象, 那麼這個函數確定具備prototype屬性。由於咱們自定義的函數均可經過new生成一個對象,因此咱們自定義的函數都有prototype 這個屬性
// 函數字面量
console.log((function(){}).prototype); // {constructor: ƒ}
// Date構造器
console.log(Date.prototype); // {constructor: ƒ, toString: ƒ, toDateString: ƒ, toTimeString: ƒ, toISOString: ƒ, …}
// Math.abs 不是構造器,不能經過new操做符生成一個新的對象,因此不含有prototype屬性
console.log(Math.abs.prototype); // undefined
prototype屬性有什麼做用呢?做用就是:函數經過new生成的一個對象, 這個對象的原型(__proto__)指向該函數的prototype屬性:
// 其中F表示一個自定義的函數或者是含有prototype屬性的內置函數
new F().__proto__ === F.prototype // true
// 經過函數字面量定義的函數的__proto__屬性都指向Function.prototype
(function(){}).__proto__ === Function.prototype // true
// 經過對象字面量定義的對象的__proto__屬性都是指向Object.prototype
({}).__proto__ === Object.prototype // true
// Object函數的原型的__proto__屬性指向null
Object.prototype.__proto__ === null // true
// 由於Function自己也是一個函數,因此Function函數的__proto__屬性指向它自身的prototype
Function.__proto__ === Function.prototype // true
// 由於Function的prototype是一個對象,因此Function.prototype的__proto__屬性指向Object.prototype
Function.prototype.__proto__ === Object.prototype // true
3、constructor無錫看男科醫院哪家好 https://yyk.familydoctor.com.cn/20612/
constructor表示一個對象的構造函數,除null和undefined,JS中的全部數據類型都有這個屬性; 咱們可經過下面的代碼來驗證一下:
null.constructor // Uncaught TypeError: Cannot read property 'constructor' of null ...
undefined.constructor // Uncaught TypeError: Cannot read property 'constructor' of undefined ...
(true).constructor // ƒ Boolean() { [native code] }
(1).constructor // ƒ Number() { [native code] }
"hello".constructor // ƒ String() { [native code] }
一個對象的constructor屬性確切地說並非存在這個對象上面的; 而是存在這個對象的原型上(若是是多級繼承需手動修改原型的constructor屬性),咱們可用下面的代碼來解釋一下:
const F = function() {};
// 當咱們定義一個函數的時候,這個函數的prototype屬性上面的constructor屬性指向本身自己
F.prototype.constructor === F; // true
對JS的原始類型(string, number, boolean, null, undefined, symbol (new in ECMAScript 2015)),它們的constructor屬性是隻讀的,不可修改:
(1).constructor = "something";
console.log((1).constructor); // 輸出 ƒ Number() { [native code] }
若是真想改這些原始類型的constructor屬性,也不是不能夠:
Number.prototype.constructor = "number constructor";
(1).constructor = 1;
console.log((1).constructor); // 輸出 number constructor
固然上面的方式不推薦