为什么这个函数表达式未定义?

时间:2015-05-04 00:37:59

标签: javascript node.js mongoose

当有人将它存储在变量中时,有人可以解释为什么这个函数变得不确定吗?

model.where({'artisan.id':id}).count(function(err, doc) {
  console.log(err, doc); // this work
})

var fn = model.where({'artisan.id':id}).count;

console.log(typeof fn); // ==> 'function'

fn(function(err, doc) { // undefined is not a function
      console.log(err, doc); 
})

感谢。

2 个答案:

答案 0 :(得分:1)

我认为错误不是从你说的那行引出的,而是从fn函数内部抛出的,因为你是用错误的上下文执行的。

当你说model.where(...).count(...)使用从where()返回的值作为其上下文执行count函数时,但当你fn(...)没有发生时,该函数将使用window上下文(严格模式下为undefined),可能无法找到导致错误的必需内部属性

var where  = model.where({
    'artisan.id': id
});

var fn = where.count;

console.log(typeof fn); // ==> 'function'

fn.call(where, function (err, doc) { // undefined is not a function
    console.log(err, doc);
})
//or
where.count(function (err, doc) {
    console.log(err, doc); // this work
})

答案 1 :(得分:0)

错误可能是因为您实际上并未将count()作为方法调用。

.count分配给fn仅保留对function本身的引用。它将与model.where({'artisan.id':id})查询对象分离,稍后将使用默认的this值 - globalundefined进行调用,具体取决于严格模式的使用。

在某些时候,它可能会尝试引用另一种方法,该方法无法通过默认this提供,例如:

function count(callback) {
    this.method(...);      // TypeError: undefined is not a function
    // global.method(...);
}

解决此问题的一种方法是.bind()方法,因此其this值已固定:

var query = model.where({'artisan.id':id});
var fn = query.count.bind(query);

fn(function (...) { ... });