2017-10-08 104 views
2

我有一个存储一堆方法的Javascript对象,并且还存储了一些变量。在正常情况下,当方法尝试访问对方或变量时,它可以很好地工作,但是如果方法从超出范围调用(例如,通过另一个回调),它们将不再能够访问该变量。从另一个对象方法内访问对象属性

实施例的jsfiddle这里:http://jsfiddle.net/3Lkuz2Lk/2/

下面是示例代码来说明该问题:

var obj = { 
 
     x: null, 
 
     func1: function() { 
 
\t  console.log('func1, x is ' + this.x); 
 
     }, 
 

 
     func2: function() { 
 
\t  console.log("func2"); 
 
     this.func1(); 
 

 
\t  var func1 = this.func1; 
 
     func3(function() { 
 
    \t  func1(); 
 
     }); 
 
     } 
 
    }; 
 

 
    function func3(callback) { 
 
\t console.log("func3"); 
 
\t return callback(); 
 
    } 
 

 
    obj.func2();

从上面的代码的输出是:

func2 
func1, x is null 
func3 
func1, x is undefined 

什么是没有不清楚为什么第二次func1被称为x是未定义的?

如果我需要做到这一点(即能够访问对象中的方法和变量,无论它们从哪个上下文中调用),我该如何实现这一点?我发现上面的方法是不干净的,因为我需要存储func1参考,以便使其可用于调用func3,并且我希望有一种更清洁/更简单的方法。

回答

1

var obj = { 
 
     x: null, 
 
     func1: function() { 
 
    console.log('func1, x is ' + this); 
 
     }, 
 

 
     func2: function() { 
 
    console.log("func2"); 
 
     this.func1(); 
 

 
    var func1 = this.func1; 
 
     func3(func1); 
 
     } 
 
    }; 
 

 
    function func3(callback) { 
 
    console.log("func3"); 
 
    return callback(); 
 
    } 
 

 
obj.func2();

这是因为这是在两种情况下不同,在第一种情况下点到对象,而在下一个这个引用全局对象/窗口。你必须做的

var obj = { 
 
     x: null, 
 
     func1: function() { 
 
    console.log('func1, x is ' + this.x); 
 
     }, 
 

 
     func2: function() { 
 
    console.log("func2"); 
 
     this.func1(); 
 

 
    var func1 = this.func1.bind(this); 
 
     func3(func1); 
 
     } 
 
    }; 
 

 
    function func3(callback) { 
 
    console.log("func3"); 
 
    return callback(); 
 
    } 
 

 
obj.func2();

1

你必须使用bind(this),阅读更多关于它here

var func1 = this.func1.bind(this); 
0

我已经简化了代码。问题在于参考。您可以致电func3,它属于自己的范围,不属于obj的范围链。所以这是指func3的范围。如果您bindthisobj到它的回调工作。

var obj = { 
 
    x: null, 
 
    func1: function() { 
 
    console.log('func1, x is ' + this.x); 
 
    }, 
 

 
    func2: function() { 
 
    console.log("func2"); 
 
    this.func1(); 
 

 
    func3(this.func1.bind(this)); 
 
    } 
 
}; 
 

 
function func3(callback) { 
 
    console.log("func3"); 
 
    return callback(); 
 
} 
 

 
obj.func2();

使用call另一个解决方案是在该小提琴http://jsfiddle.net/3Lkuz2Lk/3/