標籤:覆蓋 his 建立 false 建構函式 ret 寫入 過程 color
1 /* 2 * javascript當中 原型 prototype 對象 3 * 4 * */ 5 //首先引入 prototype的意義,為什麼要使用這個對象 6 7 //先來寫一個建構函式的物件導向執行個體 8 function Person(name ){ 9 this.name = name; 10 this.show = function(){ 11 return this.name; 12 }; 13 } 14 //執行個體化兩個對象 15 p1 = new Person("a"); 16 p2 = new Person("b"); 17 //alert(p1 == p2); // false 很顯然兩個執行個體對象不是一個對象 18 //alert(p1.show == p2.show); // false 實際上每一個對象執行個體化的時候都各自擁有自己的這個方法 19 20 21 /* 22 * 實際上,上面的例子,對於show函數來說,其實每一個Person的對象,都擁有這個方法,並且功能是一樣的,這其實是佔用記憶體的,重複累贅的 23 * 如果可以更好的 話,一個物件導向過程,相同的屬性和方法,最好還是能所有對象擁有同一份公用相同方法和屬性, 24 * 25 * 26 * 在js當中這就需要引入原型的概念: 27 * 在js中,每一個函數都有一個屬性prototype 是一個指向自己的原型對象的引用。 28 * 原型對象是一個對象, 如果我們把希望共有的方法和屬性寫入原型對象當中,就能實現,在每一個執行個體化對象不建立一個方法和屬性, 29 * 而是使用原型對象的提供的方法和屬性 30 * 31 * */ 32 33 //這是一個類 34 function Person(){ 35 36 } 37 //下面我們向這個Person類的原型對象裡面添加屬性和方法 38 Person.prototype.name = "張三"; 39 Person.prototype.show = function(){ 40 return this.name; 41 }; 42 43 //執行個體化兩個Person的對象 44 var p1 = new Person(); 45 var p2 = new Person(); 46 //alert(p1.name); //張三 47 //alert(p1.name == p2.name); //true 加入原型對象的屬性就變成了公用屬性,所有對象擁有相同一份 48 //這個時候我們給p1 增加自己的變數 覆蓋name 49 p1.name = "李四"; 50 //alert(p1.show()); //李四 這個name變數實際上沒有覆蓋原型類當中,而是p1對象自己的成員變數 51 //這個時候把p1的name刪除,再取p1的name,就又會取到原型對象的name 52 delete p1.name; 53 //alert(p1.show()); //張三 這個時候,自己沒有成員變數name , 就會使用原型對象中共有的name 54 55 //alert(p1.show == p2.show); // true 這兩個執行個體對象都沒有實現show 這個show是原型類提供的 56 57 58 /* 59 * 經過上面的分析 再來整理一下 原型對象: 60 * 61 * 1 任何一個函數 他的prototype屬性都是一個指向自己原型對象的引用 62 * 2 某個函數執行個體在調用方法或者取屬性的時候,先找自己的成員變數,如果沒有再找自己的原型對象中的共有變數 63 * 3 相同建構函式出來的所有執行個體對象的protorype 指向的原型 都和建構函式的原型是同一個原型對象 64 * 4 寫入原型中的方法和屬性是共有的,如果執行個體對象重寫,會添加私人變數 不會覆蓋原型中的內容 65 * 5 原型對象的構造器指向的就是擁有這個原型的初始的建構函式。 66 * 67 * */ 68 69 // 我們再來分析一次 70 //這是一個建構函式 71 function Person(name){ 72 this.name = name; 73 } 74 //在原型裡 添加 共有方法 75 //我們接收一下原型 76 var obj = Person.prototype; 77 obj.age = 18; 78 obj.show = function(){ 79 alert(this.name); 80 }; 81 82 //執行個體化兩個對象 83 var p1 = new Person("a"); 84 var p2 = new Person("b"); 85 //p1.show(); //a 86 //p2.show(); //b 87 //alert(p1.show == p2.show); //true 這是原型裡共有的 88 89 // Person的原型對象的構造器就是Person 90 //alert(obj.constructor); 91 92 //obj.isPrototypeOf(newobj) 這個方法用於檢查obj 是不是newobj的原型 93 //alert( obj.isPrototypeOf(p1) ); 94 //alert( obj.isPrototypeOf(p2) ); // 我們發現兩個都是true 也就是 兩個對象都有相同的原型 95 96 97 // 屬性 in 對象 可以返回對象當中有沒有屬性,但是不能判斷是原型的還是對象私人的,只要有這個屬性都返回true 98 // 對象.hasOwnProperty(屬性) 能夠檢查屬性是不是對象的私人變數 99 alert( "age" in p1 ); //true age是原型裡的屬性100 alert( p1.hasOwnProperty("age") ); //false 原型裡的屬性不是自己的屬性101 alert( p1.hasOwnProperty("name") ); //true name是自己的屬性102 103 104 //判斷是原型裡的屬性而不是自己的方法105 function prototypeHasProperty(obj , property){106 // 自己沒有這個屬性 並且 能查到這個對象可以使用這個屬性107 return !obj.hasOwnProperty(property) && ( property in obj );108 }109
JavaScript中的原型 property