JavaScript-原型理解

我是每天被自己菜醒的跳跳,嗯~就很菜!

我們所創建的每一個函數,解析器都會向函數添加一個屬性,prototype,這個屬性對應着一個對象,這個對象就是我們所謂的原型對象。

如果函數作爲普通函數調用prototype沒有任何作用的。

當函數以構造函數的形式調用時,他所創建的實例對象中都會有一個隱含屬性,指向該構造函數的原型,我們可以通過proto來訪問屬性。

 

		<script type="text/javascript">
			var a = function(){
					console.log(this.name+"構造函數")
					console.log(this)
					}
			var stuProty ={
				like:function(){
					console.log(this.name+"構造函數")
					console.log(this)
					},
				b:function(){
					console.log("喫飯睡覺打豆豆")
				}
			}
			//構造函數
			function student(name,age){
				this.name = name;
				this.age = age;
				//創建一個全局變量name和age,這裏的name指向的是window
				// this.like = a
				}
				student.prototype = stuProty
				console.log(student)
			
			// 利用構造函數自定義對象
			var stu1 = new student('狗兒',12)
			var stu2 = new student("狗三",22)
			stu1.like()
			stu2.like()
			
			
		</script>

上述代碼的原型如下圖

此處有兩個原型的原因是,1處原型在代碼中student.prototype = stuProty有這一句,給他加了原型,然後1處的原型裏面的2原型指向student。

這樣一個原型裏面有另一個原型,就構成了一個原型鏈,

 

值得注意的是如果對象的屬性和原型裏的函數重名了,自己屬性的優先級會高於原型上的優先級,如下圖

stu1和stu2使用的是同一個構造函數創建出來的實例對象,他們兩個都有一個共同的原型函數like

在1處,給stu1加了一個屬性like=12345;-->這樣不會修改原型中同名like函數的樣子,只是給stu1加了一個屬性,在2處可以看出並沒有影響。

在3處在進行調用stu1的原型函數like時報錯,但是在4處可以調用stu1的屬性like,說明在stu1中同名的屬性比原型中的函數優先級要高。

在5處就可以看出,stu1的屬性和原型是共存的。

如果想調用stu1原型上like函數,使用stu1__proto__.like()來調用,如上圖,但是此處的this是發生了改變,指向了_porto__也就是構造函數,不是指向的stu1,所以報了undefined。

在2處使用.call來改變this的指向,將原型從指向構造函數改爲指向stu1.

當然儘量不要重名啦!

 

1.原型對象相當於一個公共區域,所有同一個類的實例都可以訪問到這個原型對象,我可以將對象中共有的內容,設置到原型對象中去。

2.使用原型對象在以後創建構造函數的時候,可以將對象共有的屬性和方法,同意添加到構造函數的原型對象中去,這樣就不用了分別爲每一個對象添加,不會佔內存,也不會影響到全局作用域。

3.使用in來檢查對象中是否含有某個屬性的時候,如果對象的屬性中沒有但是原型中有,也會返回true。可以使用對象的hasOwnProperty()來檢查對象自身中是否含有該屬性。

4.原型鏈,原型對象也是對象,所以他也有原型,當我們使用或者訪問一個對象的屬性或方法時:

  • 他會先在對象自身去尋找,有則直接使用
  • 沒有則會原型中去尋找,找到了則直接使用
  • 再沒有則去原型的原型中去找,有則直接使用,一直找到Object對象的原型
  • 還沒的話就返回null

從4處我們可以看處,想要改寫Object的toString方法,只需要在實例自身上寫一個相同名字的toString方法,來改寫我們原型上的方法,來達到我們的效果。需要注意的是不要直接去改Object的方法,否則的話全局的都改了,別人用就GG了。

 

 

本人是個菜逼,理解有錯誤的地方,歡迎指正。記錄下學習筆記。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章