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

时间:2018-04-30 12:54:13

标签: javascript private private-members iife

我创建了一个小程序,当点击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>

在上面的代码中,为了保护名称,我使用IIFE并在 personDetails 中返回 displayName 方法。点击按钮,执行 printName ,进一步执行 personDetails.displayName 。以下是我的担忧 -

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

    旧方法: function displayMsg(){console.log(name); }
    新方法: personDetails.displayName = function(){console.log(&#39; Hiiii&#39;); }

3 个答案:

答案 0 :(得分:1)

  1. 是的,但只有一个全局变量。这大大降低了其他代码意外覆盖它的风险。
  2. 是。一旦代码离开您的控件并到达客户端,您就无法停止对代码的故意修改。
  3. 最小化全局变量的使用是一种减少其他代码导致的错误的可能性的策略。它不是DRM的一种形式。

答案 1 :(得分:1)

  

假设我已经成功保护了数据,但我仍然可以   通过改变控制台中的功能定义   personDetails.displayName应该避免使用。

可以通过更改返回对象的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了解详情。

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

答案 2 :(得分:1)

欢迎使用StackOverflow。请使用 tour 并访问 help center

1。这是正确的方法吗?

至少有一个&#39;关闭&#39;投票支持这个问题主要是基于意见的。那个选民是正确的,这部分问题很难明确回答。

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

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

您可以使用箭头功能进一步简化它。

2。为什么其他变量仍然暴露?

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

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

3。如何仍然可以更改此函数引用?

techniques 可让您保护此变量免受更改。但是,或许,用户可能会将personDetails重新定义为其他内容。你能保护这个吗?也许。但是,在浏览器解释之前阻止某人拦截您的Javascript,改变这些定义是什么?

关键是你只会有这么多的控​​制权。如果您不信任用户,则不应该向他们发送代码......这意味着您不应该为网络撰写文章。

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