防止覆盖Javascript函数

时间:2017-01-13 16:44:36

标签: javascript

我在JavaScript中使用模块化模式。我想知道我们是否可以阻止公共模块被覆盖。 例如,在下面的代码中, function1,function2,function3和function4 可以在外部访问,但我不想覆盖。如果覆盖了这些函数,那么我希望编译器生成错误消息

"use strict";

var $ = (function(){
return{
      function1 : function(){
          alert("this is Function1");
      },
      function2 : function(){
          alert("this is Function2");
      },
      function3 : function(){
          alert("this is Function3");
      },
      function4 : function(){
          alert("this is Function4");
      }
    };
}());


$.function1(); //will alert - this is Function1
$.function2(); //will alert - this is Function2

/* 
  I don't want to do this, If I do, then I want the compiler to generate an   
  error message
*/
$.function3=function(){
    alert('function 3 is overridden');

};
$.function3(); //will alert - function 3 is overridden

4 个答案:

答案 0 :(得分:8)

您可以使用Object.freeze(obj)将整个返回的对象设置为不可变。另请注意,您可以使用const代替var来避免重新分配对象。

'use strict';

const $ = (function() {
  return Object.freeze({
    function1: function() {
      alert('this is Function1');
    },
    function2: function() {
      alert('this is Function2');
    },
    function3: function() {
      alert('this is Function3');
    },
    function4: function() {
      alert('this is Function4');
    }
  });
})();


$.function1(); //will alert - this is Function1
$.function2(); //will alert - this is Function2

// This will now error
$.function3 = function() {
  alert('function 3 is overridden');
};
$.function3(); // will not run

答案 1 :(得分:7)

使用Object.defineProperty,您可以将该属性声明为只读。



// Make sure an error is thrown when attempting to overwrite it
// Without strict-mode, re-assigning will fail silently
'use strict';

var API = {};
Object.defineProperty(API, 'function1', {
  writeable: false,
  value: function() {
    console.log('Called function1');
  }
});

API.function1();
API.function1 = null;




答案 2 :(得分:3)

是的,可以使用Object.defineProperty方法来防止它。只需将可写可配置属性设置为false即可。您可以找到有关here

的更多信息

在您的情况下,它应该如下所示:

var $ = (function(){

var newObject = {};

Object.defineProperty (newObject, "function1", {value: function() {  alert("this is Function1");}, writable:false, configurable:false});

// etc.

return object;
}());

请注意,将可写可配置属性设置为 false 只会使 function1 属性不被覆盖。但是,由于JavaScript中的每个函数都是Function对象,因此使用 writable:false 不会保护该Function对象。因此,例如, function1 的原型仍然可以更改。

如果要以任何方式完全保存函数,则应使用Object.freeze方法。请阅读this非常有用的文章。

答案 3 :(得分:0)

有很多方法可以做到这一点。如果要在覆盖时处理该消息,可以使用gettersetter

var $ = (function(){
  var obj = {
      function1 : function(){
          alert("this is Function1");
      },
      function2 : function(){
          alert("this is Function2");
      },
      get function3() {
      	  alert("this is Function3");
      },
      set function3(value) {
      	  console.warn('You cannot override this function');
      },
      function4 : function(){
          alert("this is Function4");
      }
  };
  
  return obj
}());

// throw warning
$.function3 = 'foo';

由于使用的是IIFE,因此可以在属性内容之外定义源并进行引用。

使用ES6语法的示例:

let $ = (function () {
  let func3 = function () {
    alert('this is Function3');
  };

  class $ {
    static set function3(value) {
      return func3;
    }
    static get function3() {
      return func3;
    }
  }
  
  return $;
}());

$.function3 = 'foo';
$.function3();