js原型
```
//構造函數
function Dog(name){
this.name = name
this.age = 1
}
//實例1
var example = new Dog()
example.name = "213"
example.age = 2
console.log(example.name,example.age)--> 213 2
//實例2
var test = new Dog()
console.log(test.name,test.age)--> undefined 1
//實例化以後的兩個實例 example,test是獨立的,相互之間互不影響。
//修改其中一個的age,不會影響到另外一個。
//每個實例對象,都有本身的屬性和方法的副本。
//這不只沒法作到數據共享,也是極大的資源浪費。
//所以,原型應運而生。
//原型是構造函數的一個名爲prototype的屬性,也叫prototype對象。
//全部實例對象須要共享的屬性和方法,都放在這個對象裏面;
//那些不須要共享的屬性和方法,就放在構造函數裏面。
//實例對象一旦建立,將自動引用prototype對象的屬性和方法。
//也就是說,實例對象的屬性和方法,分紅兩種,一種是本地的,另外一種是引用的。
//如今把age放在原型中:
function Dog(name){
this.name = name
}
Dog.prototype = {
age: 1
}
var example = new Dog()
var test = new Dog()
Dog.prototype.age = 2
//修改了原型的屬性值,對全部實例生效
console.log(example.age,test.age)--> 2 2
example.age = 3
console.log(example.age) --> 3
cosnole.log(test.age) --> 2
//因爲全部的實例對象共享同一個prototype對象,
//那麼從外界看起來,prototype對象就好像是實例對象的原型,
//而實例對象則好像"繼承"了prototype對象同樣。
```
沒有原型的對象爲數很少,Object.prototype就是其中之一,不繼承任何屬性。
其餘的原型對象都是普通對象,都有原型。
全部的內置構造函數(以及大部分自定義的構造函數)都具備一個繼承自Object.prototype的原型。
#### var A = function () {}
#### var B = new A();
這個代碼說明了對象B是函數A生成的,函數和對象就是雞和蛋的關係,
可是由於最終倒騰到根上的話,Object是祖師爺,因此函數屬於對象。
JS裏面全部的東西都是對象,對象就是屬性的集合。
全部的對象上都有一個__proto__屬性,
一個對象,首先你要知道它是誰new出來的,
對象的__proto__指向new它的函數的prototype屬性;
```
var A = function () {};
var B = new A();
B.__proto__ === A.prototype;
```
那麼函數A是誰new出來的?
函數也是對象,因此它也有__proto__屬性
函數A是Function生成的,全部函數都是Function new出來的。
```
A.__proto__ === Function
// true
```
下面是最核心的東西了:函數A的prototype是誰new出來的??
A.prototype是一個對象,它有一個
```
__proto__
```
屬性,它是由Object函數new出來的
因此
```
A.prototype.__proto__ === Object.prototype
```
Object.prototype是誰建立的??
```
Object.prototype.__proto__
// null
```
so,這個鏈條是這樣的
```
B.__proto__ === A.prototype
A.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null
```
```
__proto__
```
是串起來這個鏈條的一個隱形屬性,有些瀏覽器是訪問不到這個屬性的
so,B能夠調用A.prototype上的任何屬性,一樣能夠調用Object.prototype上的任何屬性
這就是原形鏈,這就是爲何B能夠直接調用toString方法,由於toString是Object.prototype的方法
那麼你能夠在鏈條上的任何一個函數的prototype上添加東西,來測試一下B能不能訪問
答案是能夠的 好比 Object.prototype.me = "cute";
console.log(new Date().me)
// "cute";
console.log(toString().me)
// "cute"
因此爲了不變量污染,實際用途中要避免修改原型鏈上的屬性,而是在實例上作修改。前端
WEB前端學習交流羣21 598399936瀏覽器