Javascript中的數據值有兩大類:基本類型的數據值和引用類型的數據值。
基本類型的數據值有5種:null、undefined、number、boolean和string。
引用類型的數據值往大的說就1種,即Object類型。往細的說有:Object類型、Array類型、Date類型、Regexp類型、Function類型等。
當原型對象的屬性值為基本類型的數據值時,通過實例對象修改屬性值從而引起原型對象的屬性值發生變化的情況不會發生。當原型對象的屬性值為引用類型的數據值時,通過實例對象修改屬性值就可能引起原型對象的屬性值發生變化。下面舉例說明。
例1:
function Animal() {} Animal.prototype = { constructor: Animal, number: "very much", fish: ["shark","sardine"], bird:{ ability: "fly", feature: "feather" } }; var animal1 = new Animal(); var animal2 = new Animal(); //沒有改變原型的number屬性,而是自己獲得了number屬性 animal1.number = 1000; console.log(animal2.number);//very much
上例中通過構造函數Animal創建了兩個實例對象,兩個實例對象繼承了同一個原型對象的屬性。通過實例對象animal1重新設置了number屬性,結果是實例對象animal1擁有了自己的number屬性,沒有改變原型對象的number屬性值,實例對象animal2調用的number屬性還是原型對象原來的number屬性。
例2:
function Animal() {} Animal.prototype = { constructor: Animal, number: "very much", fish: ["shark","sardine"], bird:{ ability: "fly", feature: "feather" } }; var animal1 = new Animal(); var animal2 = new Animal(); var animal3 = new Animal(); //沒有改寫原型中的fish屬性,此時animal1實例對象中有了自己的fish屬性,向其自己的fish屬性中推入和彈出項不會改變原型的fish屬性。 animal1.fish = ["cold fish"]; for (var i=0;i<animal2.fish.length;i++) { console.log(animal2.fish[i]);//shark,sardine,沒有cold fish } //通過實例對象animal3向fish屬性中推入項,改變了原型對象的fish屬性,因為實例對象中沒有自己的fish屬性 animal3.fish.push("voladao");
animal3.fish[0] = "fly fish"; for (var i=0;i<animal2.fish.length;i++) { console.log(animal2.fish[i]);//fly fish,sardine,voladao }
例2中實例對象animal1創建了自己的fish屬性,沒有改變原型對象的fish屬性,所以實例對象animal2輸出的還是原型對象的fish屬性。
實例對象animal3沒有自己的fish屬性,但通過實例對象animal3向fish屬性中推入了一項,並且改變了其中的第一項的值,這些改變都發生在了原型對象的fish屬性上,所以實例對象animal2調用fish屬性時,其屬性值發生了變化。
例3:
function Animal() {} Animal.prototype = { constructor: Animal, number: "very much", fish: ["shark","sardine"], bird:{ ability: "fly", feature: "feather" } } var animal1 = new Animal(); var animal2 = new Animal(); var animal3 = new Animal(); var animal4 = new Animal(); var animal5 = new Animal(); //改寫了原型中的bird屬性 animal1.bird.ability = "run"; console.log(animal2.bird.ability);//run //創建animal3的bird屬性,沒有改變原型對象的bird屬性 animal3.bird = { eat: "fish" }; console.log(animal4.bird.eat);//undifined console.log(animal3.bird.eat);//fish animal5.bird.home = "tree"; console.log(animal4.bird.home);//tree
例3中通過實例對象animal1修改了bird屬性的ability屬性的值,實例對象animal1沒有自己的bird屬性,這個修改反映在了原型對象的bird屬性上,實例對象animal2輸出的bird.ability的值是改變后的值。
實例對象animal3創建了自己的bird屬性,這沒有改變原型對象的bird屬性,所以實例對象4的bird.eat的值為undifined。
通過實例對象animal5添加了bird屬性的home屬性,實例對象animal5沒有自己的bird屬性,這個home屬性添加到了原型對象的bird屬性上,所以animal4的bird.home的值為tree。
至於其他的引用類型的數據值有沒有以上特性,暫時還沒有想到怎么驗證,先這樣吧。