0

可能重复:
为什么自定义函数引用一直指向旧函数

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

请帮助我理解这种行为。

4

2 回答 2

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!"
于 2012-08-14T07:37:41.430 回答
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();

在您的第二个示例中,恶作剧获得了分配的原始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,但恶作剧仍然指向原始功能。

于 2012-08-14T07:51:20.920 回答