在 JS 中使用 IIFE 通过创建私有变量来保护数据

Using IIFEs in JS for protecting data by creating private variables

我创建了一个小程序,可以在单击 DOM 中的按钮时在控制台中打印一些消息。

代码-

<!DOCTYPE html>
<html>
<body>
    <button onClick="printName()">Click</button>
</body>
<script>
    const personDetails = (function() {
        let name = 'john';
        function displayMsg() {
            console.log(name);
        }
        return {
            displayName: displayMsg
        }
    })();
    function printName() {
        personDetails.displayName(); 
    }
</script>
</html>

在上面的代码中,为了保护 name,我使用了 IIFE 并在 personDetails[ 中返回了一个方法 displayName =37=]。单击按钮时,将执行 printName,进而执行 personDetails.displayName。这是我的担忧 -

  1. 这是使用 IIFE 保护数据的正确方法吗? 如果不是,请提供解决方案。这每天都变得令人困惑。
  2. 即使我们只保留1个全局变量,其他暴露 变量可以通过全局变量访问,例如 displayName 方法。
  3. 假设我已经成功保护了数据,我仍然能够 通过更改控制台中的功能定义 personDetails.displayName 应该避免。

    旧方法: 函数 displayMsg() { console.log(名称); }
    新方法: personDetails.displayName = 函数() { console.log('Hiiii'); }

  1. 是的,但是只有一个全局变量。这大大降低了其他代码意外覆盖它的风险。
  2. 是的。一旦代码离开您的控制并到达客户端,您就无法停止对代码的故意修改。

尽量减少使用全局变量是一种减少由其他代码引起错误的可能性的策略。它不是 DRM 的一种形式。

Let's say I have successfully protected the data, still I am able to change the function definition in the console through personDetails.displayName which should be avoided.

这可以通过更改返回对象的 writable 属性 的值来避免。

修改personDetails的函数赋值如下:

"use strict";
const personDetails = (function() {
    let name = 'john';
    function displayMsg() {
        console.log(name);
    }
    var obj = {};
    Object.defineProperty(obj, 'displayName', {
        value: displayMsg,
        writable: false
    });

    return obj;
})();

现在,如果有人试图覆盖 属性 值,

function printName() {
    personDetails.displayName = 10; 
}
printName();

你得到这样的错误:

Uncaught TypeError: Cannot assign to read only property 'displayName' of object '#<Object>'
    at printName (<anonymous>:17:35)

查看 this writeup 了解更多详情。

注意:这只会在严格模式下抛出错误,否则会默默地拒绝任何更改。

欢迎来到 Whosebug。请拍下tour and visit the help center.


1。这是正确的方法吗?

至少有一个 'close' 票赞成此问题主要基于意见。该选民是正确的,这部分问题很难明确回答。

所以我只想说,这至少是一种合适的方式来做到这一点。还有很多其他的。如果愿意,您可以将其简化为

const personDetails = (function() {
  let name = 'john';
  return {
    displayName: function() {
      console.log(name);
    }
  }
})()

您还可以使用箭头函数进一步简化它。

2。为什么还有其他变量暴露?

这就是此类代码的重点:创建一个 public 接口来引用一些私有数据。您也可以跳过 personDetails 并仅公开 displayName 通过返回函数而不是具有该函数的对象作为 属性.

但是如果你想使用那些数据,那么你至少需要一些 public 接口!

3。怎么这个函数引用还能改?

techniques 可以让您保护此变量不被更改。但是,也许用户会将 personDetails 重新定义为其他内容。你能保护这个吗?可能是。但是,如何阻止别人在浏览器解释之前拦截您的 Javascript,从而改变这些定义?

关键是您永远只能拥有这么多控制权。如果您不信任用户,您就不应该向他们发送代码...这意味着您不应该为网络编写代码。

使用 IIFE 来保护数据免受意外更改,甚至是善意但危险的故意更改,都很好。然而,一旦代码离开您的手,就试图假装您完全负责代码是愚蠢的。