proto
除null和undefined,js中的所有資料型別都有這個屬性; 它表示當我們訪問乙個物件的某個屬性時,如果該物件自身不存在該屬性, 就從它的__proto__屬性上繼續查詢,以此類推,直到找到,若找到最後還是沒有找到,則結果為undefined
我們把乙個物件的__proto__屬性所指向的物件叫該物件的原型;我們可以修改乙個物件的原型來讓這個物件擁有某種屬性或某個方法
// 修改乙個number型別的值的原型
const num = 1;
num.__proto__.name = "my name is 1";
console.log(num.name); // my name is 1
// 修改乙個物件的原型
const obj = {};
需注意的是,__proto__屬性雖多數瀏覽器支援,但其實它僅在ecmascript 2015規範中才被準確定義, 目的是為了給這個傳統的功能定製乙個標準,以確保瀏覽器間的相容性。通過使用__proto__屬性來修改乙個物件的原型非常慢且影響效能。 所以,若想獲取乙個物件的原型,推薦用object.getprototypeof 或reflect.getprototypeof,設定乙個物件的原型推薦用object.setprototypeof或reflect.setprototypeof
prototype
首先要記住的是,該屬性一般只存在於函式物件上; 只要是能作為構造器的函式,都包含這個屬性。即只要這個函式能通過new生成乙個新物件, 那麼這個函式肯定具有prototype屬性。因為我們自定義的函式都可通過new生成乙個物件,所以我們自定義的函式都有prototype 這個屬性
// 函式字面量
console.log((function(){}).prototype); //
// date構造器
console.log(date.prototype); //
// 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
constructor
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()
(1).constructor // ƒ number()
"hello".constructor // ƒ string()
乙個物件的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()
如果真想改這些原始型別的constructor屬性,也不是不可以:
number.prototype.constructor =
"number constructor";(
1).constructor =1;
console.
log((1
).constructor)
;// 輸出 number constructor
當然上面的方式不推薦 js原型和繼承
一.原型與建構函式 js所有的函式都有乙個prototype屬性,這個屬性引用了乙個物件,即原型物件,也簡稱原型。這個函式包括建構函式和普通函式,我們講的更多是建構函式的原型,但是也不能否定普通函式也有原型。譬如普通函式 function f alert f.prototype instanceof...
JS的原型和繼承
除null和undefined,js中的所有資料型別都有這個屬性 它表示當我們訪問乙個物件的某個屬性時,如果該物件自身不存在該屬性,就從它的 proto 屬性上繼續查詢,以此類推,直到找到,若找到最後還是沒有找到,則結果為undefined 我們把乙個物件的 proto 屬性所指向的物件叫該物件的原...
JS原型繼承和call繼承
首先建立animal和bird兩個構造器 var animal function var bird function 怎麼能在bird中同樣實現animal共有的eat屬性?var bird function this fly function 這種直接複製 實現的方式很low,而且很費事 原型繼承...