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

发布于 2022-09-02 16:09:20 字数 337 浏览 14 评论 0

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

   this.area = function( str) {
       console.log(eval(str)());    //能正确调用
       //提示pi is not defined,该如何调用??
       console.log(new Function('return '+str).call());
   };
}
var c= new Circle();
c.area('pi');

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

掩饰不了的爱 2022-09-09 16:09:20

原因:通过new Function生成的函数对象的外部词法环境是全局环境,而不是包裹它的那个函数的词法环境。所以它不能访问到外层函数(以及外层函数的外层函数)中定义的变量。

15.3.2.1 new Function

Pass in the Global Environment as the Scope parameter

换句话说,它的“作用域链”绕过了外层的n层函数,直接链接到了全局作用域。

傻比既视感 2022-09-09 16:09:20
var Circle = function() {
   var pi = function(){
       return '3.14159';
    };

   this.area = function( str) {
       console.log(eval(str)());    //能正确调用
       //提示pi is not defined,该如何调用??
       //console.log(new Function('return '+str).call());
       console.log(pi);
   };
}
var c= new Circle();
c.area('pi');

如果只是想调用的话,可以这样写.

故事还在继续 2022-09-09 16:09:20

上面已经解释了为什么访问不到,我这里按照你的要求给出个方案,看看是不是你要的

function MyClass() {
    var privateMethods = {};

    function m1(a, b) {
        console.log('this is a private method in MyClass, m1', a, b);
    }

    function m2(a, b) {
        console.log('this is a private method in MyClass, m2', a, b);
    }

    privateMethods = {
        m1: m1,
        m2: m2
    };

    this.invokePrivateMethod = function(methodName) {
        if(typeof privateMethods[methodName] == 'function') {
            privateMethods[methodName].apply(null, Array.prototype.slice.call(arguments, 1))
        } else {
            throw new Error('there is no such a private method named ' + methodName);
        }
    };
}

// example
var myClass = new MyClass();
myClass.invokePrivateMethod('m');  // => throw error
myClass.invokePrivateMethod('m1', 'arg1', 'arg2'); // invoke m1 with parameters
myClass.invokePrivateMethod('m2'); // invoke m2 without parameters
月隐月明月朦胧 2022-09-09 16:09:20

new Function

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
new Function生成的函数对象不会形成闭包结果,它们总是在全局作用域下生成,也就是这个函数对象是挂在全局对象下的。

eval

eval输入参数是一个字符串信息,JS在运行时通过编译器会编译字符串表示的代码,形成的作用域和直接写代码的效果相同

new Function('return '+str).call();语句中new Function('return '+str)创建了一个函数对象,call方法调用这个函数对象。如果作用域正确,调用的结果是返回一str表示的对象的字符串表示
如果str标示在JD解析器解析后是一个函数对象并且你想调用它,那么需要再调用一次

new Function('return '+str).call()();

new Function('return '+str)()();

一定要调用new Function,那么可以使用如下方式,供参考

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

   this.area = function( str) {
       console.log(eval(str)());    //能正确调用
       console.log(new Function(str,'return '+str).call(null,pi)());
   };
}
var c= new Circle();
c.area('pi');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文