原型是js裏非常重要的一個概念,很多更高級的概念需要有原型的基礎,類似於,我們js裏的繼承,原型就是其中一種實現方式,還有通過原型模式創建對象等等,這都需要原型基礎,這裏主要通過Chorme的調試器,來看看到底原型和對象到底是什麼。
首先我們先寫一些測試用的代碼
function Person(){
var name = 'qfy';
var password = '123'
}
function Man(){
var name = 'ds';
var password = '12fsdf3'
}
Person.prototype.age = 23;
Person.prototype.name = 'li';
Person.prototype.say = function(name){
console.log(this.name)
}
Man.prototype.name = 'af';
Man.prototype.say = function(name){
console.log(this.name)
}
這是兩個構造函數,分別是Person和Man,並且分別給兩個構造函數的原型上添加了屬性name
之後我們通過構造函數創建對象
var person = new Person()
我們看一下person在谷歌調試下console.log出了什麼
是一個Person創建的對象,裏面有一個__proto__
屬性。這裏面有有我們定義在Person原型上的name屬性值,和say方法,還有一個constructor指向Person構造函數。
這裏的__proto__
就是指向Person構造函數的原型,這就是原型鏈,屬性都在原型鏈上,當我們的對象本身不存在這個屬性是,就會向上查找原型鏈裏是否包含屬性。
console.log(person.__proto__ === Person.prototype)//true
person.say()// li 通過原型鏈找到了name=li,可以看到上面的__proto__歷史有name屬性的
person.__proto__ = new Man() //我們可以通過__proto__來調整原型鏈,雖然__proto__是瀏覽器的自己的屬性,並不是標準的屬性。
console.log(person.name) //af
當我們使用字面量方法定義prototype時,我們需要重新指定原型的構造函數指向
Person.prototype = {'name': 'li','head': 'sf'}
//指向了全局
console.log(Person.prototype.constructor)//function Object() { [native code] }
//我們需要在中間加一段代碼,將指向還原
Person.prototype.constructor = Person;
我們可以通過最簡單原型繼承來更深的理解一下
var person = function(){
this.name = 'sfs'
};
person.prototype = new Person()
var person1 = new person()
person1.say()//sfs
console.log(person1)
繼承了Person的say方法,和一些屬性雖然new的是person,但依舊可以使用Person的方法
這就是原型鏈,我們可以通過他來一層一層的找。我們new的時候得到的都是原型鏈裏的屬性和方法,除非構造函數中用this,否則我們是訪問不到的。