淺析原型和原型鏈

        昨天看對原型概念有了一點點的興趣,雖說了解的不是很透徹,但是還是多多少少有一點收穫的,就自己的一些學習到的東西做一個小小的總結。主要是結合了課本、網上資源和一些視頻來學習的。

        原型涉及到了原型、原型鏈和構造函數。而且在每個博客的講解中都涉及到了構造函數的內容,那就先從構造函數的概念和作用談起。

    構造函數

        構造函數我們應該都很清楚了,在學習C#的時候接觸過這個概念。在JS的學習中:構造函數的特點:

    a:構造函數的首字母必須大寫,用來區分於普通函數

    b:內部使用的this對象,來指向即將要生成的實例對象

    c:使用New來生成實例對象

例如:

//構造函數
function Person(name,age){
     this.name = name;    
     this.age = age;   
     this.sayHello = function(){   
         console.log(this.name +"say hello");
    }
}

var boy = new Person("bella",23);    
boy.sayHello(); // bella say hello

構造函數的缺點:

    所有的實例對象都可以繼承構造器函數中的屬性和方法。但是,同一個對象實例之間,無法共享屬性

    解決思路:

      a:所有實例都會通過原型鏈引用到prototype

      b:prototype相當於特定類型所有實例都可以訪問到的一個公共容器

      c:那麼我們就將重複的東西放到公共容易就好了

如下顯示:

function Person(name,age){
    this.name = name;
    this.age = age;
    this.sayHello = function(){
        console.log(this.name + "say hello");
    }
}
var girl = new Person("bella",23);
var boy = new Person("alex",23);
console.log(girl.name);  //bella
console.log(boy.name);   //alex
console.log(girl.sayHello === boy.sayHello);  //false

    原型

        prototype(原型):是function對象的一個熟悉性,定義了構造函數製造出的對象的公共祖先(公共屬性和方法)通過構造函數產生對象,可以繼承改變原型的屬性和方法。原型也是對象。

      __proto__(隱士原型):每個對象的__proto__屬性指向自身構造函數的prototype;

        constructor(構造器):返回對創建此對象的數組函數的作用。

prototype屬性的作用

  js中每個數據類型都是對象,除了null 和 undefined,而每個對象都是繼承自一個原型對象,只有null除外,它沒有自己的原型對象,最終的Object的原型爲null

function Person(name,age){
    this.name = name;
    this.age = age;
}
Person.propotype.sayHello = function(){
    console.log(this.name + "say hello");
}
var girl = new Person("bella",23);
var boy = new Person("alex",23);
console.log(girl.name);  //bella
console.log(boy.name);   //alex
console.log(girl.sayHello === boy.sayHello);  //true

 

     

     由上圖可以看出,prototype是構造函數的屬性,而consructor則是構造函數的prototype屬性所指向的那個對象,也就是說constuctor是原型對象的屬性。

  constructor屬性是定義在原型對象上面,意味着也可以被實例對象繼承。

 

  •        如果有原型,那麼就一定有函數。每一個對象有一個屬性叫__proto__;這個屬性就是對象的原型。對象有原型,那麼原型也是對象,原型也有原型。
  • 所有的函數是對象,繼承自Function.prototype
  •  Function.prototype是對象,繼承自Object.prototype
  • Object.prototype是對象,繼承自null
  • obj是對象,繼承自Object.prototype
  • Function是對象,繼承自Function.prototype
  • Function是函數,繼承自Function.prototype

         這就涉及到了原型鏈。

      原型鏈

        首先看一段代碼:

<!DOCTYPE html>
<html> 
	<head>
		<title></title>
		<style type="text/css">
			
		</style>
		<script type="text/javascript">
			var o = {}; //{ name:"我是祖宗"};
			
			var f1 = function() {
				// this.name = "我是亞當";
			};
			f1.prototype=o;
			var foo1 = new f1();
			
			var f2 = function() {
				// this.name = "夏娃";
			}
			var foo2 = new f2();
			foo2.__proto__ = foo1;
			
			var f3 = function() {
				// this.name = "我是人類";
			};
			f3.prototype = foo2;
			
			var foo3 = new f3();
			alert(foo3.name);
		</script>
	</head>
	<body>
	</body>
</html>

        上面代碼的運行結果:

1)當所有的this.name,都沒有註釋的話:運行結果----》我是人類

2)當f3的this.name 註釋掉,運行結果-----》我是夏娃

3)當f2和f3中的this.name註釋,運行結果是-----》我是亞當

4)當f1,f2,f3中的this.name註釋,運行結果----》我是祖宗,

5)當全部被註釋掉,運行結果是undefined;

   js成員的訪問規則

  • o.方法()
  • 首先在o當前這個類型中尋找該成員的定義,如果存在該成員的定義
  • 那麼就直接使用改成員
  • 如果該成員不再當前類型中,就訪問其原型(原型鏈中的上一級)
  • 以此類推,直到null位置

        上圖中的原型鏈:

原型鏈
對象 __proto__ prototype

constructor

foo Foo.prototype --- ---
obj Object.prototype --- ---
Foo Function.prototype Foo.prototype  
Foo.prototype Object.prototype --- Foo
Function Function.prototype Function.prototype  
Function.Prototype Object.prototype --- Function
obj Object.prototype --- ---
Object Function.prototype Object.prototype ---
Object.prototype null --- Object

參考鏈接:

https://www.cnblogs.com/thonrt/p/5900510.html

https://www.cnblogs.com/wjyz/p/10219106.html

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