Javascript “班级失利”;这";通过引用调用原型函数时的作用域

Javascript “班级失利”;这";通过引用调用原型函数时的作用域,javascript,function,reference,scope,prototype,Javascript,Function,Reference,Scope,Prototype,有人能给我解释一下为什么“b”返回未定义的值,以及我如何解决这个问题吗?当我通过引用调用原型函数时,“this”范围为什么会丢失 MyClass = function(test) { this.test = test; } MyClass.prototype.myfunc = function() { return this.test; } var a = new MyClass('asd').myfunc(); var b = new MyClass('asd').my

有人能给我解释一下为什么“b”返回未定义的值,以及我如何解决这个问题吗?当我通过引用调用原型函数时,“this”范围为什么会丢失

MyClass = function(test) {
this.test = test;
}

MyClass.prototype.myfunc = function() {       
   return this.test;
}

var a = new MyClass('asd').myfunc();
var b = new MyClass('asd').myfunc;

// Returns "asd" correctly
console.log(a)

// Returns undefined??
console.log(b())
==编辑/解决方案===

正如plalx所写,在我的例子中正确的解决方案是使用.bind()。结果如下所示:

MyClass = function(test) {
    this.test = test;
}

MyClass.prototype.myfunc = function() {       
   return this.test;
}

var a = new MyClass('asd').myfunc();
var b = new MyClass('asd'),
    bfunc = b.myfunc.bind(b)

// Returns "asd" correctly
console.log(a)

// Also returns "asd" correctly!
console.log(bfunc())

var b..
。是一个函数引用,您实际上没有调用该函数。

var b..
。是一个函数引用,您实际上并没有调用该函数。

如果您想要此行为,则需要明确地绑定this值

var c = new MyClass('asd'),
    b = c.myfunc.bind(c);


console.log(b());
var a = new MyClass('asd').myfunc();
默认情况下,
将指向
左侧.ofdot(),或者干脆调用函数的对象

注意:调用
b()
window.b()相同

将每个函数绑定到对象实例是可能的,但效率很低,因为函数将不再在实例之间共享

例如


如果需要此行为,则需要明确地绑定this值

var c = new MyClass('asd'),
    b = c.myfunc.bind(c);


console.log(b());
默认情况下,
将指向
左侧.ofdot(),或者干脆调用函数的对象

注意:调用
b()
window.b()相同

将每个函数绑定到对象实例是可能的,但效率很低,因为函数将不再在实例之间共享

例如


在这里,您将myfunc()函数的结果赋值给一个变量

var a = new MyClass('asd').myfunc();
在这里,您正在指定b变量函数引用,而不是运行它,并将结果分配给变量

var b = new MyClass('asd').myfunc;
最后,在这里:

console.log(b())
您试图记录函数b的结果,在这种情况下,b()并没有在任何地方定义,只是被分配了对函数的引用

var a = new MyClass('asd').myfunc();
试试这个:

console.log(b); // It logs [Function]
但除此之外,你的问题很难理解


请使用分号

在这里,您要将myfunc()函数的结果赋值给一个变量

var a = new MyClass('asd').myfunc();
在这里,您正在指定b变量函数引用,而不是运行它,并将结果分配给变量

var b = new MyClass('asd').myfunc;
最后,在这里:

console.log(b())
您试图记录函数b的结果,在这种情况下,b()并没有在任何地方定义,只是被分配了对函数的引用

var a = new MyClass('asd').myfunc();
试试这个:

console.log(b); // It logs [Function]
但除此之外,你的问题很难理解


请使用分号

这就是
这个
的工作原理。它是在调用函数时设置的。这就是
这个
的工作原理。它是在调用函数时设置的。这正是他想要做的。是的,一开始我很困惑-但是当你低头看他的控制台日志语句时,他在那里调用b(),在从对象检索函数之后。这正是他想要做的。是的,一开始我很困惑-但是当你低头看他的控制台日志语句时,他在那里调用b(),从对象检索函数后。有没有办法在myfunc定义处绑定它,使其始终以这种方式绑定?@evguenineverniouk有,我更新了答案,但是我不推荐它,除非您有非常特殊的需要。你为什么需要这个?对,这正是我想要避免的。我想将函数定义为原型的一部分,以确保它被正确地共享,但是,我还想确保我可以按照我最初的回答中所述通过引用调用这些函数。听起来好像不可能。@EvgueniNaverniouk,在这种情况下,当您需要存储函数引用时,我只需使用
bind
。您还可以存储一个对象,比如
var ref={fn:theFunction,thisArg:theObject}
,然后使用
ref.fn.call(theObject)
。有没有办法在myfunc定义处绑定它,以便它总是以这种方式绑定?@EvgueniNaverniouk是的,我更新了答案,但是我不推荐它,除非您有非常具体的需要。你为什么需要这个?对,这正是我想要避免的。我想将函数定义为原型的一部分,以确保它被正确地共享,但是,我还想确保我可以按照我最初的回答中所述通过引用调用这些函数。听起来好像不可能。@EvgueniNaverniouk,在这种情况下,当您需要存储函数引用时,我只需使用
bind
。您还可以存储像
var ref={fn:theFunction,thisArg:theObject}
这样的对象,然后使用
ref.fn.call(theObject)