一茅糜、prototype(原型/原型對象)
- 每個函數(shù)天生自帶一個屬性
prototype
莺葫,它是一個對象。- 只要函數(shù)定義好以后腻暮,這個
prototype
就存在了彤守;所以,函數(shù)和prototype
可以理解為伴生關(guān)系哭靖。- 構(gòu)造函數(shù)也是函數(shù)具垫,構(gòu)造函數(shù)有
constructor
和prototype
,可以向原型對象prototype
里面添加內(nèi)容试幽。
function Person(){}
//Person.prototype已經(jīng)出生了
//向prototype上添加一些屬性和方法
Person.Prototype.sayHi = function(){}
console.log(Person.prototype)
// {
// sayHi: ?()
// constructor: ? Person()
// __proto__: Object
// }
二筝蚕、__proto__
- 每個對象自帶一個屬性
__proto__
,指向所屬構(gòu)造函數(shù)的prototype
- 實例化對象也是一個對象铺坞,也有
__proto__
屬性
function Person(){}
Person.prototype.sayHi = function(){
console.log("hello")
}
let p1 = new Person()
console.log(p1) //Person {}
console.log(p1.__proto__ === Person.prototype)//true
因為
p1
是Person
實例化出來的對象起宽,所以p1
所屬的構(gòu)造函數(shù)就是Person
p1.__proto__
指向所屬構(gòu)造函數(shù)的prototype
三、對象訪問機制
當訪問一個對象的成員時济榨,如果對象本身有坯沪,則直接返回結(jié)果;如果沒有擒滑,會自動去
__proto__
上訪問腐晾;一直找尋到頂級對象的__proto__
叉弦,最終沒找到則返回undefined
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function () {
console.log('Hello world')
}
let p1 = new Person("lxc", 18)
console.log(p1.name, p1.age, p1.sayHi)
p1身上并不存在sayHi屬性,它向上找尋時藻糖,到了
p1.__proto__
淹冰,而p1.__proto__
剛好指向了Person.prototype
,所以找到了sayHi
利用
prototype
巨柒、__proto__
和對象訪問機制樱拴,解決了構(gòu)造函數(shù)的不合理;屬性直接寫在構(gòu)造函數(shù)體內(nèi)洋满,方法寫在構(gòu)造函數(shù)的prototype
上
protytype作用:為了寫一些方法給構(gòu)造函數(shù)的實例對象使用晶乔,因為構(gòu)造函數(shù)的每個實例都可以訪問它的
prototype
- 看到這里應(yīng)該有一個疑問?
上面說到:
- 每個對象都有
__proto__
屬性牺勾,隨便一個實例化對象的__proto__
都是其所屬構(gòu)造函數(shù)的prototype
;- 每個函數(shù)都有一個
prototype
瘪弓,它是一個對象每個構(gòu)造函數(shù)也是對象,那構(gòu)造函數(shù)這個對象的
prototype
應(yīng)該也有__proto__
禽最,它指向了誰腺怯?
所以,這里來了第三條定義:當一個對象沒有準確的構(gòu)造函數(shù)來實例化的時候川无,看作是內(nèi)置構(gòu)造函數(shù)Object的實例呛占。
var arr = [];//Array的實例
var obj = {};//Object的實例
function Person(){}
var p1 = new Person;//Person的實例
var time = new Date();//Date的實例
var fn = function(){};//Function的實例(只要是函數(shù),就是Function的實例)
Person.prototype;//Object的實例
Array.prototype;//Object的實例
結(jié)論:任何一個對象開始出發(fā)懦趋,按照
__proto__
向上查找晾虑,都能找到Ojbect.prototype
,我們把這個用__proto__
串聯(lián)起來的鏈狀結(jié)構(gòu)仅叫,叫做原型鏈
原型鏈的作用:為了對象訪問機制服務(wù)