js修正モデルの属性使用紹介

3267 ワード

Javascriptでは、特定のタイプのすべてのインスタンスにアクセスできる属性と方法をプロトタイプに定義しています.多くの場合、プロトタイプの属性に対して値を新たにする必要があります.もし方法が間違ったら、思いがけないことがあります.
基本タイプの定義は以下の通りです.
 
  
function Person(){}

Person.prototype={
constructor:Person,
name:"person",
age:100,
friends:["a","b"],
getName:function(){
return this.name;
}
};
二つのPersonの例を定義して、インスタンス中のname属性を修正します.テストコードは以下の通りです.
 
  
var p1=new Person();
var p2=new Person();

document.write(p1.name+"
"); //person
document.write(p2.name+"
"); //person

p1.name="p1";
document.write(p1.name+"
"); //p1
document.write(p2.name+"
"); //person

document.write(p1.hasOwnProperty("name")+"
"); //true
document.write(p2.hasOwnProperty("name")+"
"); //false

document.write(Object.keys(p1)+"
"); //name
document.write(Object.keys(p2)+"
"); //
document.write(Object.getOwnPropertyNames(Person.prototype)+"
"); //constructor,name,age,friends,getName
document.write(Person.prototype.name+"
"); //person
テストを経て、p 1.name="p 1"はnameの値を修正したのではなく、インスタンスp 1に新しいname属性が追加されました.プロトタイプのname属性をカバーしています.今後の判断から、この時点でp 1のname属性はプロトタイプの属性ではなく、インスタンス属性であることが分かります.後のObject.keys(p 1)p 1のこの例では、name属性が一つ増えていますが、p 2にはありません.jsにおけるすべての伝達は値伝達であり、この値は参照の種類を指す指針でありうるので、等号はこの参照の対象を修正するという意味ではなく、元の引用関係を切り替えて、次にコードを通してこの問題を説明します.
 
  
var obj=new Object();
obj.name="obj";

function changeObj(o){
o.name="changed";
o=new Object();
o.name="newObj";
}
changeObj(obj);

document.write(obj.name); //changed
changedObjメソッドでは、o=new Object()はパラメータoの値を修正するのではなく、元の引用関係を遮断しましたので、結果はnewObjではなくchangedです.
次に修正の第一例のプロトタイプの中のfriends属性をテストします.この属性は引用タイプです.
 
  
p1.friends.push("c");
document.write(p1.friends+"
"); //a,b,c
document.write(p2.friends+"
"); //a,b,c

p1.friends=["x","y","z"];
document.write(p1.friends+"
"); //x,y,z
document.write(p2.friends+"
"); //a,b,c

document.write(p1.hasOwnProperty("friends")+"
"); //true
document.write(p2.hasOwnProperty("friends")+"
"); //false

document.write(Object.keys(p1)+"
"); //name,friend
document.write(Object.keys(p2)+"
"); //
document.write(Object.getOwnPropertyNames(Person.prototype)+"
"); //constructor,name,age,friends,getName
document.write(Person.prototype.friends+"
"); //a,b,c
今回のテスト結果は最初のテストとほぼ同じです.等号で修正すると、元の参照を切断してインスタンスの新しい属性を作成し、プロトタイプの同名属性をカバーします.
これらの2つのテスト結果に基づいて、インスタンスにおいて直接にプロトタイプの値属性を修正することができないことがわかった(もちろん、このような値のタイプはプロトタイプに定義されるべきではないが、ここでのコードの例はこの知識点のみを示しており、実際の意味はない)