JavaScript引用了混乱

时间:2012-08-14 06:56:39

标签: javascript

  

可能重复:
  why self defining function reference keeps pointing to the old function

我对javascript引用行为很困惑。请看一下这段代码,非常清楚javscript在传递引用时没有创建新的内存位置。

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正在为scareMe和恶作剧创建2个独立的内存位置

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

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

scareMe(); // "Double boo!"

请帮助我理解这种行为。

2 个答案:

答案 0 :(得分: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

第二块:

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!"

答案 1 :(得分:0)

在你的第一个例子中,我认为你试图使用Object继承,你的原型分配不合适, 将原型分配给现有原型时,将导致左侧原型引用另一个原型。 然后,只需要在代码中指定原型变量的位置,即:

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();

在你的第二个例子中,恶作剧获得了原始的scareMe功能。 scareMe功能输出“Boo!”并重新分配scareMe函数变量。 这意味着最外面的“var scareMe”现在指向一个不同的功能(返回“Double Boo!”)。 但由于恶作剧仍然指向原始函数,它将始终执行原始代码(输出“Boo!”并重新分配scareMe)。

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

“scareMe”的第一个电话重新分配了scareMe,但恶作剧仍然指向原来的功能。