V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
charlie21
V2EX  ›  Node.js

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

  •  
  •   charlie21 · 2016-04-05 15:51:31 +08:00 · 3668 次点击
    这是一个创建于 2936 天前的主题,其中的信息可能已经有所发展或是发生改变。
    // 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' }; 这句 失效 即 让 函数不被覆盖 .. ?

    12 条回复    2016-05-06 13:52:55 +08:00
    charlie21
        2
    charlie21  
    OP
       2016-04-05 16:17:25 +08:00
    @chairuosen 是我想要的 谢谢

    补个英文文档,其中 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
    murmur
        3
    murmur  
       2016-04-05 16:20:37 +08:00
    object.freeze?
    w88975
        4
    w88975  
       2016-04-05 16:23:19 +08:00
    是类似于 const ?
    charlie21
        5
    charlie21  
    OP
       2016-04-05 17:08:25 +08:00
    @w88975 写一个实例方法,并确保它是安全的:让类的实例仅能 “使用” 这个实例方法(而不能去 “覆盖” 这个实例方法,让这个实例方法的方法体不被覆盖。如果想要覆盖,先生成 子类做多态 )
    w88975
        6
    w88975  
       2016-04-05 17:25:48 +08:00
    @charlie21 试了一下 Object.defineProperty ,之前一直不知道有这个函数存在.
    inmyfree
        7
    inmyfree  
       2016-04-05 17:46:35 +08:00
    ! import 哈哈
    charlie21
        8
    charlie21  
    OP
       2016-04-05 19:59:58 +08:00
    我不知道我的感觉对不对:
    js 里的 object , object literal notation 的 method , 类的 prototype 都很容易一不小心就给 override 了
    只有 defineProperty 能显式表明 writable false 即 不能被覆盖
    morethansean
        9
    morethansean  
       2016-04-06 09:16:27 +08:00
    @charlie21 如果只是想一个 object 不再被做任何改变,就用 freeze 呗。原型链怎么会被“一不小心就给 override ”,写了那么久的 js 就连属性被 override 带来了 bug 都几乎很少发生。
    ChunlinLi
        10
    ChunlinLi  
       2016-04-16 22:50:48 +08:00
    @charlie21
    没遇到过误覆盖的情况.

    另外, 注意 defineProperty 会有一定的 性能惩罚. defineProperty 放在构造器中会使 new 操作慢百倍左右.
    qwerasdf
        11
    qwerasdf  
       2016-05-05 01:45:53 +08:00
    或许你会需要阅读这个
    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
    elrrrrrrr
        12
    elrrrrrrr  
       2016-05-06 13:52:55 +08:00
    get 方法?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1138 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 18:24 · PVG 02:24 · LAX 11:24 · JFK 14:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.