使用JS多态性&方法重写

时间:2015-07-12 06:45:18

标签: javascript object inheritance

我目前正在研究javascript的基础知识,并且我很难理解这个图表(如下所示)。当调用FirmAnswer.get()时,为什么值为42 !!?不应该是未定义的!因为如果我没有弄错中的这个 函数中的<。> 函数fn2()指的是firmAnswer。

信用图表所有者

enter image description here

5 个答案:

答案 0 :(得分:3)

这是一个麻烦的话题,我会给你的。

this引用firmAnswer是正确的,但即使firmAnswer没有明确分配val属性,val也不是undefined。为什么?因为val原型链中的firmAnswer位于更高位置,正如调用Object.create所确定的那样,并且如您提供的图表所示。

评估this.val时,这是幕后的事件序列:

  1. 是否有val属性直接附加到this?不。查看this的原型(对象answer)。
  2. 是否有val属性直接附加到answer?是。使用它。

答案 1 :(得分:3)

  

因为如果我没有弄错,那么在函数fn2()中返回this.val指的是firmAnswer

是的,确实如此,但是当您尝试从对象检索属性(val)时,如果对象本身没有该属性,则JavaScript引擎会查找对象的原型。 firmAnswer的原型是answer(因为这是Object.create用来设置的), val,所以使用属性的值。这称为原型链,是原型继承的关键。

这是一个稍微简单的例子:

// Create an object with a `val`
var p = {
  val: "p's value"
};

// Create an object using `p` as its prototype
var o = Object.create(p);

// Use `val` from `o` -- since `o` doesn't have `val`, the engine
// looks to `p`
snippet.log(o.val); // "p's value"

// Give `o` its own `val`
o.val = "o's value";

// Use it
snippet.log(o.val); // "o's value"

// Since this is based on whether `o` has `val` at all
// (not the *value* of `val`), we can *remove* `val`
// from `o` and start using `p`'s again:

// Remove `val` from `o` entirely
delete o.val;

// Use `val` again -- and we're back to using `p`'s
snippet.log(o.val); // "p' s value ""
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

答案 2 :(得分:2)

var firmAnswer = Object.create(answer);

以上陈述意味着'firmAnswer&#39;继承了所有的回答&#39; pro&amp;方法,answer.get()方法由firmAnswer.get()覆盖,但val属性不是。

答案 3 :(得分:2)

以下是它的运行方式:

  1. 您致电firmAnswer.get();
  2. vm调用fn2this设置为firmAnswer;
  3. vm抓取this.valthis设置为firmAnswer;
  4. firmAnswer是否定义了属性val?不,让我们看看firmAnswer原型;
  5. firmAnswer的原型已使用Object.create(answer)指定,因此它是answer;
  6. answer是否定义了属性val?是的,它是42;
  7. 因此,在步骤3中,this.val42;
  8. 步骤2返回42!!

答案 4 :(得分:2)

'this'是firmAnswer,但它仍然继承自答案,因为使用Object.create设置了带答案的继承。所以它本身就找.val,找不到它,然后回答并从那里拿起它。

有关Object.create的信息,请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create