gpt4 book ai didi

javascript - 这是做私有(private)功能的好方法吗?

转载 作者:数据小太阳 更新时间:2023-10-29 04:51:37 26 4
gpt4 key购买 nike

刚刚在 CoffeeScript 中打错字时看到了一些有趣的代码。我得到以下代码

var Mamal, mam;

Mamal = (function() {
var __priv_func;

function Mamal() {}

Mamal.prototype.simple_var = 5;

Mamal.prototype.test = function() {
return __priv_func(this);
};

__priv_func = function(instance) {
return alert(instance.simple_var);
};

return Mamal;

})();

mam = new Mamal();
mam.simple_var = 10;
mam.test();

现在我已经阅读了很多关于 javascript 中的模块模式以及为什么它是一件坏事(需要更多内存,创建时间更长......),但当然好处是拥有真正的私有(private)函数/变量。上面的代码不是创建私有(private)函数的好方法吗(这对变量不起作用,除非你想要静态私有(private)变量)因为函数只在闭包中创建一次?

模块模式的优点之一也是函数的执行速度,因为代码不必查找原型(prototype)链。从理论上讲,这会带来相同的速度提升吗?

最佳答案

为了突出我提出的观点,因为显然这个问题不仅仅是标题:

  • 是的,模块模式是一种很好且常用的方法来创建私有(private)(呃,本地)数据(函数或其他),并导出某种接口(interface)。由于函数是创建变量作用域的唯一方法,因此它是创建私有(private)函数的唯一方法。
  • 因为这些函数将被从 Mamal 创建的所有对象共享。 ,它们对于功能继承模式没有用(对功能继承的引用已从问题中删除)。
  • 原型(prototype)链中的查找没有性能改进,因为无论如何都需要遍历原型(prototype)链才能到达您的私有(private)函数。


  • 要解决更新帖子中的特定问题点:

    "Would this be a good way to do private functions?"



    当然,但那是因为将一个函数嵌套在另一个函数中是限定函数范围的唯一方法。

    "Now I've read alot about the module pattern in javascript and why its a bad thing..."



    对于一次性使用模块,我没有看到任何问题。此外,在模块函数退出后不再需要的变量引用的任何数据都可以免费用于垃圾收集。如果它们是全局性的,情况就不会如此,除非您将它们无效。

    "...of course the upside is having truly private functions/variables..."



    是的,尽管有些人会反对使用“私有(private)”一词。可能“本地”是一个更好的词。

    "...this wouldn't work for variables, unless you wanted static private variables..."



    是的,尽管有些人可能会反对使用“静态”这个词。

    "Wouldn't the above code be a good way to create private functions...as the function is only created once in the closure?"



    再次是的,嵌套函数是使它们“私有(private)”或更确切地说是本地的唯一方法。

    但是,是的,只要函数只需要访问对象的公共(public)属性(任何可以访问该对象的代码都可以访问)而不是构造函数的局部变量,那么您应该只创建一次这些函数,无论是或不使用模块模式。

    "One of the upsides of the module pattern is also the execution speed of functions as the code doesn't have to look up the prototype chain. Would this theoretically give the same speed improvements?"



    不,您没有直接导出您的私有(private)函数,而是调用它们的唯一方法是遍历原型(prototype)链。

    但是如果你放弃原型(prototype)链,直接在创建的对象上添加函数作为属性,那么你会有一些改进。

    这是一个例子:
    Mamal = (function() {
    var __priv_func;

    function Mamal() {
    this.test = __priv_func;
    }

    Mamal.prototype.simple_var = 5;

    __priv_func = function() {
    return alert( this.simple_var );
    };

    return Mamal;

    })();

    现在您已经在查找 test 时消除了原型(prototype)链。函数,以及包装的函数调用,而您仍在重用 __priv_func .

    剩下的唯一原型(prototype)是 simple_var ,您也可以将其直接带到对象上,但是当您尝试修改其值时,无论如何都会发生这种情况,因此您不妨将其留在那里。

    原答案:

    如果您在谈论模块模式,在其中(通常)在 IIFE 中设置一堆代码,然后导出可以访问匿名函数中的变量的方法,那么是的,这是一个很好的方法,而且很漂亮常见的。
    var MyNamespace = (function () {
    // do a bunch of stuff to set up functionality
    // without pollution global namespace

    var _exports = {};

    _exports.aFunction = function() { ... };
    _exports.anotherFunction = function() { ... };

    return _exports;
    })();

    MyNamespace.aFunction();

    但是在您的示例中,除非您决定使用上述模块模式,否则我看不到典型构造函数的优势。

    按照现在的方式,可以像这样完成相同的功能,而无需任何全局污染,也无需包装函数:
    var Mamal, mam;

    Mamal = function() {};

    Mamal.prototype.test = function() {
    return console.log(this.simple_var);
    };

    Mamal.prototype.simple_var = 5;

    mam = new Mamal();
    mam.simple_var = 10;
    mam.test();

    " Wouldn't the above code be a good way to create private functions (this wouldn't work for variables, unless you wanted static private variables) as the function is only created once in the closure?"



    鉴于上面重写的代码,该函数仍然只创建一次。原型(prototype)对象在从构造函数创建的对象之间共享,因此它也只创建一次。

    "One of the upsides of functional inheritance is also the execution speed of functions as the code doesn't have to look up the prototype chain. Would this theoretically give the same speed improvements?"



    在您的代码中,该函数是通过原型(prototype)链中的函数调用的,因此它具有相同的开销,加上在变量范围内查找本地函数并调用该函数的开销。

    因此,两次查找和两次函数调用,而不是一次查找和一次调用。

    关于javascript - 这是做私有(private)功能的好方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8426099/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com