Nodejs js 公有方法通过 new Function 方式调用私有方法的问题?

Nodejs js 公有方法通过 new Function 方式调用私有方法的问题?

var Circle = function() {
var pi = function(){
return ‘3.14159’;
};

this.area = function( str) { console.log(eval(str)()); //能正确调用 console.log(new Function('return '+str)); 如何调用?? }; } var c= new Circle(); c.area(‘pi’);


11 回复

LZ 这个写法……可以当面试题了,考察变量作用域……典型的反面教材……


new function 和 eval 完全没区别,都是毫无安全性可言,你漏了执行 function 这一步而已

当我使用 new Function('return '+str).call());的时候,会提示 pi is not defined. 应该是 new Function 的时候需要使用 apply 传入作用域,不知道传啥?

如果是这样的话就说明 new function 不能访问闭包了,建议去查一下 ecma 规范吧

Note: Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope. When running them, they will only be able to access their own local variables and global ones, not the ones from the scope in which the Function constructor was called. This is different from using eval with code for a function expression.

http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function

不是 FUNCTION 的问题.
c.area(‘pi’); 这里的 pi 肯定取不到你构造函数里的静态方法 pi 的.
写代码还是少带点奇技淫巧的好.你这里传 function 作为参数.

new Function 只可访问全局变量哦~

var Circle = function() {
var pi = function(){
return ‘3.14159’;
};

var locals = {
pi: pi
};

this.area = function( str) {
return locals[str] && localsstr;
};
}
var c= new Circle();
c.area(‘pi’);

new Function 可以传参哦

应该是这儿
http://www.ecma-international.org/ecma-262/5.1/index.html#sec-10.4.2

eval: 10.4.2 的 2.b, 2.c , eval 会把当前执行 context 设为调用者的 context (VariableEnvironment)
所以能调到局部变量

new Function: 10.4.3 的 5 和 7 ,把当前执行环境设为 NewDeclarativeEnvironment(Function.prototype.[[Scope]]),所以得不到局部变量

就没有人给楼主一个正确的姿势吗。。
http://jsbin.com/vefadiyidi/edit?js,console

在Node.js中,通过new Function方式动态创建并调用函数时,确实可以绕过常规的访问控制机制来调用所谓的“私有方法”。然而,这种做法并不推荐,因为它破坏了封装性和代码的可维护性。私有方法通常是以某种方式(如命名约定或Symbol)来标识,并在模块或类内部使用,以避免外部直接访问。

下面是一个简单的示例,展示了如何通过new Function来调用私有方法,但请注意,这仅用于演示目的,并不推荐在实际项目中使用。

class MyClass {
  #privateMethod() {
    return 'Private Method Called';
  }

  publicMethod() {
    const privateMethodCaller = new Function('return this.#privateMethod()');
    return privateMethodCaller.bind(this)();
  }
}

const instance = new MyClass();
console.log(instance.publicMethod());  // 输出: Private Method Called

在这个例子中,#privateMethod是一个私有方法,我们通过new Function创建了一个动态函数,并使用bind方法将其this上下文绑定到类实例上,从而能够调用私有方法。

然而,这种做法破坏了私有方法的封装性,并且可能导致代码难以理解和维护。在实际开发中,应该尊重封装原则,避免使用这种技巧。如果需要控制方法的访问权限,应该使用适当的访问修饰符(如JavaScript中的命名约定或TypeScript中的private关键字),并设计合理的API接口。

回到顶部