如何让 Nodejs 中的 js 函数有类似 readonly 的不被覆盖的效果?

发布于 1周前 作者 sinazl 来自 nodejs/Nestjs

如何让 Nodejs 中的 js 函数有类似 readonly 的不被覆盖的效果?

// test.js
// > node test.js

// define Edge function Edge(x, y) { this._x = x; this._y = y; }; Edge.prototype = { get x(){ return this._x }, set x(val){ console.log(‘x is readonly’) }, // 设置 x 为只读且无法更改 get y(){ return this._y }, set y(val){ console.log(‘y is readonly’) } }; Edge.prototype.showLocation = function() { return ‘Location: (’ + this._x + ', ’ + this._y + ‘).’ };

// use Edge var eg = new Edge(23,23); console.log(eg.x); console.log(eg.y); console.log(eg.showLocation()); // #=> Location: (23, 23). eg.x = 30; // 测试能否被修改,期望不能被改 eg.y = 30; console.log(eg.showLocation()); // #=> Location: (23, 23). 这是我想要的效果

eg.showLocation = function() { return ‘I am joking’ }; // 测试能否被修改,期望不能被改 console.log(eg.showLocation()); // #=> I am joking 这不是我想要的效果

请问如何让 eg.showLocation = function() { return 'I am joking' }; 这句 失效 即 让 函数不被覆盖 .. ?


13 回复

是我想要的 谢谢

补个英文文档,其中 defineProperty 的 value 不只是 值,还可以是 any valid JavaScript value (number, object, function, etc).
这样就可以做到让函数作为 value ,并控制它为只读了

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters

是类似于 const ?

写一个实例方法,并确保它是安全的:让类的实例仅能 “使用” 这个实例方法(而不能去 “覆盖” 这个实例方法,让这个实例方法的方法体不被覆盖。如果想要覆盖,先生成 子类做多态 )

试了一下 Object.defineProperty ,之前一直不知道有这个函数存在.

! import 哈哈

我不知道我的感觉对不对:
js 里的 object , object literal notation 的 method , 类的 prototype 都很容易一不小心就给 override 了
只有 defineProperty 能显式表明 writable false 即 不能被覆盖

如果只是想一个 object 不再被做任何改变,就用 freeze 呗。原型链怎么会被“一不小心就给 override ”,写了那么久的 js 就连属性被 override 带来了 bug 都几乎很少发生。


没遇到过误覆盖的情况.

另外, 注意 defineProperty 会有一定的 性能惩罚. defineProperty 放在构造器中会使 new 操作慢百倍左右.

或许你会需要阅读这个
G 强类型
http://blog.csdn.net/rflyee/article/details/44736133
强类型,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了
强类型定义语言是类型安全的语言。(变量声明类型)
弱类型的变量, 一个变量可以多次赋不同数据类型的值。比如 接连执行 s = 5; s = “five”; 是可以的
强类型定义语言带来的严谨性能够有效的避免许多错误。

强类型 JavaScript 的解决方案
http://www.ruanyifeng.com/blog/2015/02/strong-typing-javascript.html

在 Node.js 中,如果你希望某个 JavaScript 函数具有只读属性,防止它被覆盖,可以通过使用 Object.defineProperty 方法来定义该函数的属性,并设置其 writable 属性为 false。下面是一个示例代码:

const myObject = {};

// 定义一个函数
function myFunction() {
  console.log('This is my readonly function.');
}

// 使用 Object.defineProperty 将函数添加到对象中,并设置为只读
Object.defineProperty(myObject, 'myReadonlyFunction', {
  value: myFunction,
  writable: false,
  configurable: false, // 防止属性被删除或重新定义
  enumerable: true     // 默认为 true,表示属性是可枚举的
});

// 尝试调用该函数
myObject.myReadonlyFunction(); // 输出: This is my readonly function.

// 尝试覆盖该函数,将会失败并抛出错误
try {
  myObject.myReadonlyFunction = function() {
    console.log('Trying to overwrite, but this will fail.');
  };
} catch (error) {
  console.error('Error:', error.message); // 输出: Error: Cannot assign to read only property 'myReadonlyFunction' of object '#<Object>'
}

在这个示例中,myObject.myReadonlyFunction 被定义为只读属性,因此尝试覆盖它时会抛出错误。这种方法可以有效地保护你的函数不被意外覆盖。注意,虽然 configurable 属性设置为 false 也会阻止属性被删除或重新定义,但通常设置为只读(writable: false)已经足够保护函数不被覆盖。

回到顶部