JavaScript prototype属性と修正対象

5528 ワード

JavaScript prototype属性
定義と用法
プロトタイプの属性は、オブジェクトに属性と方法を追加する能力を持っています.
構文
object.prototype.name=value
実例
この例では、プロトタイプ属性をどのように使用してオブジェクトに属性を追加するかを示します.
<script type="text/javascript">
	function employee(name,job,born) {
		this.name=name;
		this.job=job;
		this.born=born;
	}

	var bill=new employee("Bill Gates","Engineer",1985);
	employee.prototype.salary=null;
	bill.salary=20000;

	document.write(bill.salary);
</script>
例:
<html>
<head>
<title>test prototype</title>
</head>

<body>

<script type="text/javascript">
	function employee(name, job, born) {
		this.name = name;
		this.job = job;
		this.born = born;
	}

	var bill = new employee("Bill Gates", "Engineer", 1985);

	employee.prototype.salary = null;
	bill.salary = 20000;

	document.write(bill.salary);
</script>

</body>

</html>
出力:
20000
===================================================================================================================================
JavaScript prototype修正対象
ECMAScriptを使うことで、オブジェクトを作成するだけでなく、既存のオブジェクトの挙動を変更することもできます.
prototype属性は、構造関数の属性と方法を定義するだけでなく、ローカルオブジェクトに属性と方法を追加することもできます.
新しい方法を作成します.(既存の方法で新しい方法を作成します.)
プロトタイプの属性で既存のクラスのために新しい方法を定義することができます.自分のクラスを処理するように.例えば、Number類のtoStringの方法を覚えていますか?パラメータ16を渡すと、16進数の文字列が出力されます.この方法のパラメータが2である場合、バイナリの文字列が出力されます.数値オブジェクトを直接16進文字列に変換する方法を作成できます.この方法を作成するのはとても簡単です.
Number.prototype.toHexString = function() {
  return this.toString(16);
};
 
この環境では、キーワードthisはNumberの例を指すので、Numberのすべての方法に完全にアクセスすることができる.このコードがあれば、以下の操作が可能です.
var iNum = 15;
alert(iNum.toHexString());	//   "F"
数字15は16進数のFに等しいので、警告は「F」と表示されます.
 
既存の名前を変更する方法
既存の方法について、より分かりやすい名前を付けることもできます.例えば、Arayクラスに2つの方法enqueue()とdequeue()を追加して、既存のpush()とshift()の方法を繰り返し起動させるだけでよい.
Array.prototype.enqueue = function(vItem) {
  this.push(vItem);
};

Array.prototype.dequeue = function() {
  return this.shift();
};
既存の方法とは関係ない方法を追加します.
もちろん、既存の方法とは無関係な方法を追加することもできる.例えば、ある項目の配列内の位置を判断するとしたら、このようなことができるローカル方法はない.簡単に次の方法を作成できます.
Array.prototype.indexOf = function (vItem) {
  for (var i=0; i<this.length; i++) {
    if (vItem == this[i]) {
	  return i;
	}
  }

  return -1;
}
 
この方法のindexOf()は、String類の同名の方法と一致しており、配列内で各項目を検索して、転送された項目と同じ項目が発見されるまでは.同じ項目が見つかったら、その項目の位置を返します.そうでなければ、-1を返します.このような定義があれば、下記のコードを作成できます.
var aColors = new Array("red","green","blue");
alert(aColors.indexOf("green"));	//   "1"
ローカルオブジェクトに新しい方法を追加します.
最後に、ECMAScriptにローカルオブジェクトごとに新しい方法を追加するには、Objectオブジェクトのprototype属性で定義する必要があります.前の章で述べたように、すべてのローカルオブジェクトはObjectオブジェクトを継承していますので、Objectオブジェクトを変更すると、すべてのローカルオブジェクトに反応します.例えば、警告出力対象の現在の値を追加する方法では、以下のコードが使用されてもよい.
Object.prototype.showValue = function () {
  alert(this.valueOf());
};

var str = "hello";
var iNum = 25;
str.showValue();		//   "hello"
iNum.showValue();		//   "25"
ここでは、StringオブジェクトとNumberオブジェクトは、ObjectオブジェクトからshowValueメソッドを引き継ぎ、それぞれのオブジェクトにこの方法を呼び出して、「hello」と「25」を表示します.
既存の方法を再定義
既存のクラスに新しい方法を定義できるように、既存の方法を再定義することもできます.前の章で説明したように、関数名は関数のポインタだけを指すので、他の関数を簡単に指すことができます.地元の方法を修正したら、toString()のように、どうなりますか?
Function.prototype.toString = function() {
  return "Function code hidden";
}
 
前のコードは完全に合法的で、運行結果は完全に予想通りです.
function sayHi() {
  alert("hi");
}

alert(sayHi.toString());	//   "Function code hidden"
覚えているかもしれませんが、Functionオブジェクトの章でFunctionのtoStringメソッドが一般的に出力されるのは関数のソースコードです.この方法を上書きすると、他の文字列に戻ります.ところで、toStringの指し示す原始関数はどうなりましたか?廃棄されているので、不要なメモリユニットを回収します.元の関数を復元する方法がないので、元の方法をカバーする前に、より安全な方法は、後に使用するための指針を保存することです.新しい方法でも元の方法を呼び出すことができます.
Function.prototype.originalToString = Function.prototype.toString;

Function.prototype.toString = function() {
  if (this.originalToString().length > 100) {
    return "Function too long to display.";
  } else {
    return this.originalToString();
  }
};
このコードでは、第1行のコードは、現在のtoString()メソッドに対する参照を属性origginal ToStringに保存します.その後,カスタム法でtoString()法をカバーした.新しい方法は、関数ソースコードの長さが100より大きいかどうかを確認します.もしそうであれば、エラー情報を返します.関数コードが長すぎると説明します.そうでなければ、オリジナルToString()メソッドを呼び出して、関数のソースコードを返します.
極晩バインディング(Very Late Binding)
技術的には、極めて遅いバインディングは存在しません.この本はこの用語を用いてECMAScriptの中の一つの現象を説明します.つまり、対象を実用化してからその方法を定義することができます.たとえば:
var o = new Object();

Object.prototype.sayHi = function () {
  alert("hi");
};

o.sayHi();
多くのプログラム設計言語では、オブジェクトを実用化する前にオブジェクトを定義する方法が必要です.ここで、方法sayHi()はObjectクラスの一例を作成した後に追加される.伝統的な言語では、このような操作は聞いたことがないだけでなく、Objectオブジェクトのインスタンスを自動的に付与し、すぐに使用することができます.
注意:極めて遅いバインディング方法はお勧めしません.追跡と記録が難しいからです.でも、この可能性を知るべきです.
 
 
転載声明:本文は自http://www.w3school.com.cn/js/pro_jsobjectmodifyingn.asp