0

重複の可能性:
自己定義関数参照が古い関数を指し続ける理由

私はJavaScriptの参照動作にかなり混乱しています。このコードを見てください。新しいメモリの場所を作成せずに参照を渡す際の JavaScript は非常に明確です。

Human.prototype = Monkey.prototype;
Human.prototype.name = "human";
Human.prototype.work = "love";

Joker.prototype = Human.prototype;
Joker.prototype.name = "joker";
Joker.prototype.act = "awesome";

joker = new Joker ();
human = new Human ();
human.name = 'joker'; 

これを見てください。javascript が 2 つの別々のメモリ ロケーションを scareMe と prank 用に作成していることは明らかです。

var scareMe = function () {
   alert("Boo!");
   scareMe = function () {
     alert("Double boo!");
  };
};

var prank = scareMe; 
prank(); // "Boo!"
prank(); // "Boo!"

scareMe(); // "Double boo!"

この動作を理解するのを手伝ってください。

4

2 に答える 2

0

最初の例では、プロトタイプを既存のプロトタイプに割り当てると、左側のプロトタイプが他のプロトタイプを参照するため、プロトタイプの割り当てが適切ではないオブジェクト継承を使用しようとしていたと思います。次に、これらのプロトタイプ変数をコードのどこに割り当てるかだけの問題です。つまり、次のようになります。

Human.prototype = Monkey.prototype;
//Human.prototype.name = "human";  -- not here
Human.prototype.work = "love";

Joker.prototype = Human.prototype;
Joker.prototype.name = "joker";
Joker.prototype.act = "awesome";

Human.prototype.name = "human";  // but here

joker = new Joker ();
human = new Human ();
alert(human.name) // outputs "human"

ただし、オブジェクトの継承には代わりにこれを使用する必要があります。

Human.prototype = new Monkey();

2 番目の例では、prank に元の scareMe 機能が割り当てられます。scareMe 関数は「Boo!」を出力します。そして、scareMe 機能変数を再割り当てします。これは、最も外側の「var scareMe」が別の関数 (「Double Boo!」を返す) を指すようになったことを意味します。しかし、prank は依然として元の関数を指しているため、常に元のコードを実行します ("Boo!" を出力し、scareMe を再割り当てします)。

// i.e.: reverse the call order:
scareMe(); // "Boo!"
prank(); // "Boo!"
prank(); // "Boo!"

「scareMe」の最初の呼び出しで scareMe が再割り当てされますが、prank は依然として元の関数を指しています。

于 2012-08-14T07:51:20.920 に答える
0

最初のブロック:

Monkey = function(){};

Human = function(){};
Human.prototype = new Monkey(); // This is how you have to inherit properties of Monkey
Human.prototype.name = "human";
Human.prototype.work = "love";

Joker= function(){};
Joker.prototype = new Human();  // This is how you have to inherit properties of Human
Joker.prototype.name = "joker";
Joker.prototype.act = "awesome";

joker = new Joker ();
human = new Human ();
alert(joker.name);  // shows joker
alert(human.name);   // shows human

実際、プロトタイプでプロパティを作成することはお勧めしません。(参照: http://css.dzone.com/articles/ecmascriptnext-classes )

Monkey = function(){
    this.name = "monkey";
    this.work = "jump";
};

Human = function(){
    this.name = "human";
    this.work = "love";
};
Human.prototype = new Monkey(); // This is how you have to inherit properties of Monkey

Joker = function(){
    this.name = "joker";
    this.work = "awesome";
};

Joker.prototype = new Human();  // This is how you have to inherit properties of Human

joker = new Joker ();
human = new Human ();
alert(joker.name);  // shows joker
alert(human.name);   // shows human

2 番目のブロック :

var scareMe = function () {       // `scareMe` is a global variable 
   alert("Boo!");
   scareMe = function () {       //  value of global `scareMe` will be changed when original `scareMe` gets executed for the first time
     alert("Double boo!");
  };
};

var prank = scareMe; 
prank(); // "Boo!" - because `prank` is original scareMe. but this execution changes value of `scareMe` 
prank(); // "Boo!" - same happens

scareMe(); // "Double boo!" - `scareMe` is having new function. it shows "Double boo!"
于 2012-08-14T07:37:41.430 に答える