对象文字动态键

时间:2015-09-23 05:05:41

标签: javascript node.js

我正在关注here中的节点功能编程教程,但当我尝试实施第12课的代码时,如下所示

function Spy(target, method) {
  var store={};
  var self=this;
  var copy=target[method];
  store[target[method]]=0;
  console.log(store);
  console.log(store[target[method]]);
    target[method]=function(){
        store[target[method]]+=1;
      return copy.apply(this,arguments);
    };

  return {count:store[target[method]]}; 
}

var spy = Spy(console, 'error');

console.error('calling console.error');
console.error('calling console.error');
console.error('calling console.error');

console.log(spy.count);

我在Spy中得到console.log(store)返回一个包含函数的对象。此外,Spy的最终返回return {count:store[target[method]]};返回undefined。任何人都可以解释这两个背后的原因吗?谢谢

2 个答案:

答案 0 :(得分:1)

因为在设置store[target[method]]=0;之后您将target[method]设置为等于某个函数,这会混淆store[target[method]]的值并使其未定义。您似乎希望在copy上使用return值:

return {count:store[copy]}; 

虽然在这种情况下count仍然是0,但这没有帮助。这是因为您直接在Spy {prop: value, ...}中返回了一个对象,因此您无法在Spy函数中对其进行真正的修改。虽然为了解决这个问题,将对象{count:store[copy]}定义为构造函数(var returnObj = {count:store[copy]};)中的变量,然后返回该变量:return returnObj。现在,您可以更新returnObj.count内的[target[method]]

这是有效的,因为JavaScript中的Object是通过引用传递的。

function Spy(target, method) {
  var store={};
  var self=this;
  var copy=target[method];
  store[target[method]]=0;
  var returnObj = {count:store[copy]};

    target[method]=function(){
        returnObj.count+=1;
        return copy.apply(this,arguments);
    };

  return returnObj; 
}

var spy = Spy(console, 'error');

console.error('calling console.error');
console.error('calling console.error');
console.error('calling console.error');

console.log(spy.count);

答案 1 :(得分:0)

我想用你在代码中添加的其他日志来解释这些内容

function Spy(target, method) {
  var store={};
  var self=this;
  var copy=target[method];  // #0.1
  store[target[method]]=0; //  #0.2
  console.log('Before :: store', store); // #1
  console.log('Before :: target[method]', target[method]); // #2

  target[method]=function(){
      store[target[method]]+=1;
      return copy.apply(this,arguments);
  }; // #3

  console.log('After :: store', store);  // #4
  console.log('After :: target[method]', target[method]);  // #5
  return {count:store[target[method]]}; // #6
}

var spy = Spy(console, 'error');
console.log(spy.count);

target[method]是一个类似于function () { [native code] }的函数(用js lib中编写的代码替换本机代码)。

0.2,您正在使用此字符串形式的函数({1}}对象并将其值分配给store。 因此,您的商店对象看起来像

0

`Before :: store { 'function () { [native code] }': 0 }` #1target[method]的原生函数。

现在#2您正在为#3分配一个新功能,所以现在target[method]将引用您的新功能。

因此,在target[method],您的商店对象保持不变。 (因为key是函数的字符串化值。)

#4

但是由于您在`After :: store { 'function () { [native code] }': 0 }` 中进行了分配,因此您的#3值已更改为新功能

target[method]

现在在After :: target[method] function (){ store[target[method]]+=1; return copy.apply(this,arguments); } ,你试图从#6对象中不存在的商店对象中获取一个键,这就是为什么它store并将count的值存储到{ {1}}