Estoy usando un patrón modular en JavaScript. Me pregunto si podemos evitar que se anulen los módulos públicos. Por ejemplo, en el siguiente código se puede acceder a función1, función2, función3 y función4 pero no quiero anular. Si estas funciones se anulan, entonces quiero que el compilador genere un mensaje de error

"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
5
greencheese 13 ene. 2017 a las 19:44

3 respuestas

La mejor respuesta

Puede usar Object.freeze(obj) para establecer que todo el objeto devuelto sea inmutable. Además, tenga en cuenta que puede usar const en lugar de var para evitar que el objeto sea reasignado.

'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
8
BDawg 3 jul. 2018 a las 13:25

Sí, se puede evitar utilizando el método Object.defineProperty. Simplemente configure el atributo escribible y configurable en falso. Puede encontrar más información sobre eso aquí

En su caso, debería verse así:

var $ = (function(){

var newObject = {};

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

// etc.

return object;
}());

Tenga en cuenta que establecer los atributos escribible y configurable en falso simplemente evita que se sobrescriba la propiedad function1 . Sin embargo, dado que cada función en JavaScript es una Función, ese objeto Function no está protegido mediante writable: false . Entonces, por ejemplo, el prototipo de la función1 todavía se puede cambiar.

Si desea guardar completamente sus funciones para que no se modifiquen, debe usar el método Object.freeze. Lea este artículo muy útil.

3
d.popov 9 oct. 2018 a las 11:51

Usando Object.defineProperty usted puede declarar la propiedad como de solo lectura.

// 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;
8
Mike Cluck 13 ene. 2017 a las 16:48