javascript
javascript(JS)高级进阶(二) 函数原型
函數的原型(prototype)
- 每個函數都有一個prototype屬性,它默認指向一個Object 空對象(稱為原型對象)
- 原型對象中有一個屬性constructor,它指向函數對象
構造器屬性
每個函數都有 "prototype" 屬性,即使我們沒有提供它。
默認的 "prototype" 是一個只有屬性 constructor 的對象,屬性 constructor 指向函數自身。
像這樣:
function Rabbit() {}/* default prototype Rabbit.prototype = { constructor: Rabbit }; */我們可以檢查一下:
function Rabbit() {} // by default: // Rabbit.prototype = { constructor: Rabbit }alert( Rabbit.prototype.constructor == Rabbit ); // true通常,如果我們什么都不做,constructor 屬性可以通過 [[Prototype]] 給所有 rabbits 使用:
function Rabbit() {} // by default: // Rabbit.prototype = { constructor: Rabbit }let rabbit = new Rabbit(); // inherits from {constructor: Rabbit}alert(rabbit.constructor == Rabbit); // true (from prototype)我們可以使用 constructor 屬性來創建一個新對象,該對象使用與現有對象相同的構造器。
像這樣:
function Rabbit(name) {this.name = name;alert(name); }let rabbit = new Rabbit("White Rabbit");let rabbit2 = new rabbit.constructor("Black Rabbit");當我們有一個對象,但不知道它使用了哪個構造器(例如它來自第三方庫),并且我們需要創建另一個類似的對象時,用這種方法就很方便。
但是,關于 "constructor" 最重要的是……
……JavaScript 自身并不能確保正確的 "constructor" 函數值。
是的,它存在于函數的默認 "prototype" 中,但僅此而已。之后會發生什么 —— 完全取決于我們。
特別是,如果我們將整個默認 prototype 替換掉,那么其中就不會有 "constructor" 了。
例如:
function Rabbit() {} Rabbit.prototype = {jumps: true };let rabbit = new Rabbit(); alert(rabbit.constructor === Rabbit); // false因此,為了確保正確的 "constructor",我們可以選擇添加/刪除屬性到默認 "prototype",而不是將其整個覆蓋:
function Rabbit() {}// 不要將 Rabbit.prototype 整個覆蓋 // 可以向其中添加內容 Rabbit.prototype.jumps = true // 默認的 Rabbit.prototype.constructor 被保留了下來或者,也可以手動重新創建 constructor 屬性:
Rabbit.prototype = {jumps: true,constructor: Rabbit };// 這樣的 constructor 也是正確的,因為我們手動添加了它給原型對象添加屬性(一般都是方法)
-
作用:它的所有實例對象自動擁有原型對象的方法
(實例對象可以訪問到)
1、讀取對象的屬性值時,會自動到原型鏈中找
2、設置對象屬性值時,不會查找原型鏈,如果當前對象沒有此屬性,直接添加此屬性并設置值
3、方法一般定義在原型中,屬性一般通過構造函數定義在對象本身上
顯式原型 / 隱式原型
1、 每個函數function都有一個prototype,即顯式原型(屬性)
2、 每個實例對象都有一個____proto____ ,即稱為隱式原型(屬性)
3、 對象的隱式原型的值等于對應構造函數的顯式原型的值
function Person(){this.dog = 'sss'}const p = new Person()console.log(p.__proto__); // { constructor: f Person() }console.log(Person.prototype); // { constructor: f Person() } // 即 p實例對象的 隱式原型__proto__ == Person構造函數的 顯示原型 prototype4、總結:
- 函數的prototype屬性:在定義函數時自動添加的,默認值一個空的Object對象
- 實例對象的__proto__屬性:創建對象時自動添加的,默認值是其構造函數的prototype屬性值
原型鏈
1、函數的顯式原型指向的對象默認式空Object對象(object除外)
-
因為它的__proto__為nulll
-
A instanceof B
-
查找時 如果B函數的顯式原型對象在A對象的原型鏈接上,返回true,否則返回false
2、所有函數都是Function的實例(包含它自己)
3、Object的原型對象是原型鏈的盡頭
總結
以上是生活随笔為你收集整理的javascript(JS)高级进阶(二) 函数原型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小众商家想要打开市场该如何实现
- 下一篇: 【JS从入门到精通】08-构造函数与原型