JavaScript 访问在调用函数中声明的变量
JavaScript accessing variables declared in calling function
很难解释我的问题,所以我发布了一些代码。
function caller(func) {
function printMessage(message) {
console.log(message);
}
func();
}
function callee() {
printMessage('hello world');
}
caller(callee);
我想从被调用方访问 printMessage,但就目前而言,这会引发 ReferenceError。如果可能的话,我想避免全局声明 printMessage。
你可以将你想在callee
内部使用的函数作为参数传递给callee
;只要调用者可以访问,那么 callee
不在乎它是在哪里定义的:
function caller(func) {
....
func(printMessage);
}
function callee( func ) {
func("hello world");
}
你可以做的一件事是 'caller' 调用传递给它的函数,并打印返回值。
function caller(func) {
function printMessage(message) {
console.log(message);
}
printMessage(func());
}
function callee() {
return 'hello world';
}
function callee2() {
return 'hello world 2';
}
caller(callee);
caller(callee2);
编辑
阅读您对问题的评论后,这可能更适合 OO 方法,例如:
//--- Base 'libary' caller ---//
var caller = function() {
}
//--- Add out printMessage function to our base libary ---//
caller.prototype.printMessage = function(message){
console.log(message);
}
//--- Users 'libary' callee ---//
var callee = function() {
caller.call(this);
//--- Our users libary has a printing function ---//
this.print = function ( message ) {
this.printMessage("callee > " + message);
}
}
callee.prototype = Object.create(caller.prototype); // Set callee's prototype to caller's prototype
callee.prototype.constructor = callee; // Set constructor back to callee
//--- Using the users libary ---//
var userLibary = new callee();
userLibary.print("hello world"); // 'callee > hello world'
//--- The original libary's print method is still accessible ---//
userLibary.printMessage("hello world"); // 'hello world'
基本上,你不能。嵌套 printMessage
仅限于 caller
范围。
您可以通过其 calee.caller
原型访问 caller
构造函数,但它 "locked" 仅在调用者的范围内..
仅供参考:
function caller(func) {
function printMessage(message) {
console.log(message);
}
func();
}
function callee() {
//you can access the caller's constructor from prototype..
var callerFunc = arguments.callee.caller.prototype;
console.log(callerFunc);
//you can get the actual code
var code = arguments.callee.caller.toString();
console.log(code);
//but you can't invoke the nested function which is under
//caller scope only...will throw ReferenceError
printMessage('hello world');
}
caller(callee);
jsfiddle:
http://jsfiddle.net/ufxnoaL1/
另请注意,arguments.callee
将不受支持,应该 not be used
Warning: The 5th edition of ECMAScript (ES5) forbids use of
arguments.callee() in strict mode. Avoid using arguments.callee() by
either giving function expressions a name or use a function
declaration where a function must call itself.
eval 似乎相当优雅地实现了这一点。
function caller(func) {
function printMessage(message) {
console.log(message);
}
eval('(' + func.toString() + ')();');
}
function callee() {
printMessage('hello world');
}
caller(callee);
很难解释我的问题,所以我发布了一些代码。
function caller(func) {
function printMessage(message) {
console.log(message);
}
func();
}
function callee() {
printMessage('hello world');
}
caller(callee);
我想从被调用方访问 printMessage,但就目前而言,这会引发 ReferenceError。如果可能的话,我想避免全局声明 printMessage。
你可以将你想在callee
内部使用的函数作为参数传递给callee
;只要调用者可以访问,那么 callee
不在乎它是在哪里定义的:
function caller(func) {
....
func(printMessage);
}
function callee( func ) {
func("hello world");
}
你可以做的一件事是 'caller' 调用传递给它的函数,并打印返回值。
function caller(func) {
function printMessage(message) {
console.log(message);
}
printMessage(func());
}
function callee() {
return 'hello world';
}
function callee2() {
return 'hello world 2';
}
caller(callee);
caller(callee2);
编辑
阅读您对问题的评论后,这可能更适合 OO 方法,例如:
//--- Base 'libary' caller ---//
var caller = function() {
}
//--- Add out printMessage function to our base libary ---//
caller.prototype.printMessage = function(message){
console.log(message);
}
//--- Users 'libary' callee ---//
var callee = function() {
caller.call(this);
//--- Our users libary has a printing function ---//
this.print = function ( message ) {
this.printMessage("callee > " + message);
}
}
callee.prototype = Object.create(caller.prototype); // Set callee's prototype to caller's prototype
callee.prototype.constructor = callee; // Set constructor back to callee
//--- Using the users libary ---//
var userLibary = new callee();
userLibary.print("hello world"); // 'callee > hello world'
//--- The original libary's print method is still accessible ---//
userLibary.printMessage("hello world"); // 'hello world'
基本上,你不能。嵌套 printMessage
仅限于 caller
范围。
您可以通过其 calee.caller
原型访问 caller
构造函数,但它 "locked" 仅在调用者的范围内..
仅供参考:
function caller(func) {
function printMessage(message) {
console.log(message);
}
func();
}
function callee() {
//you can access the caller's constructor from prototype..
var callerFunc = arguments.callee.caller.prototype;
console.log(callerFunc);
//you can get the actual code
var code = arguments.callee.caller.toString();
console.log(code);
//but you can't invoke the nested function which is under
//caller scope only...will throw ReferenceError
printMessage('hello world');
}
caller(callee);
jsfiddle: http://jsfiddle.net/ufxnoaL1/
另请注意,arguments.callee
将不受支持,应该 not be used
Warning: The 5th edition of ECMAScript (ES5) forbids use of arguments.callee() in strict mode. Avoid using arguments.callee() by either giving function expressions a name or use a function declaration where a function must call itself.
eval 似乎相当优雅地实现了这一点。
function caller(func) {
function printMessage(message) {
console.log(message);
}
eval('(' + func.toString() + ')();');
}
function callee() {
printMessage('hello world');
}
caller(callee);