js的原型鏈

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瀏覽器

相關文章
相關標籤/搜索