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

这些语法扩充大家是怎么组织代码的呢?

  •  
  •   Livid · 2014-05-09 06:04:23 +08:00 · 3494 次点击
    这是一个创建于 3883 天前的主题,其中的信息可能已经有所发展或是发生改变。
    JavaScript 本身缺少一些比较方便的字符串方面的函数,有的时候为了方便一些操作,就会用这样的方式给 String 加方法:

    String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };

    像这样的代码大家一般是放到项目的什么位置呢?最好的做法应该是怎样的呢?
    11 条回复    2014-05-09 12:58:10 +08:00
    iwege
        1
    iwege  
       2014-05-09 07:25:11 +08:00   ❤️ 1
    lodash.js/underscore.js 然后require
    leofml
        2
    leofml  
       2014-05-09 09:21:39 +08:00 via iPad   ❤️ 1
    直接加prototype上,让别人debug比较麻烦。
    所以一般是自己写一个util继承lodash,然后扩展util。
    bolasblack
        3
    bolasblack  
       2014-05-09 09:24:28 +08:00   ❤️ 2
    如果只是要操作字符串的话,可以使用 underscore.string http://epeli.github.io/underscore.string/

    node 项目的话,可以在 app 目录下创建一个 helpers 目录,用来放这些函数(总觉得 node 项目的很多地方都可以直接参考 Ruby on Rails 的做法)

    不过还是不太推荐直接扩展原型……
    zack
        4
    zack  
       2014-05-09 09:31:20 +08:00
    一般自定义的通用模块我会放在lib目录下
    Mutoo
        5
    Mutoo  
       2014-05-09 09:36:45 +08:00   ❤️ 4
    > for(var key in "abc"){console.log(key);}
    0
    1
    2

    > String.prototype.endsWith = function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };

    > for(var key in "abc"){console.log(key);}
    0
    1
    2
    endsWith

    直接修改原生对象不是一件好事,如果非要这么做,建议用
    Object.defineProperty(String.prototype, {enumerable:false, ...})
    并明确 enumerable 为 false. 不然指不定哪些地方就出问题了。
    luin
        6
    luin  
       2014-05-09 10:02:57 +08:00   ❤️ 1
    1. 加 prototype 至少要这样加,否则会有 @Mutoo 的问题:

    Object.defineProperty(String.prototype, "endsWith", {
    value: function(suffix) {
    return this.indexOf(suffix, this.length - suffix.length) !== -1;
    }
    });

    而且当你用 for in 而且没写 hasOwnProperty 时,你的编辑器应该给警告(如果没有一定要配置一下)。

    2. 这样的修改原生对象的代码可以直接加到程序入口出,这样所有从入口 require 的模块也可以用这些 sugar 了。

    3. 至于这样的实现好不好,利不利于 debug 就见仁见智了。underscore vs sugar
    zythum
        7
    zythum  
       2014-05-09 10:44:33 +08:00   ❤️ 1
    Object.defineProperty 只是试用于高级浏览器。
    String.prototype.endsWith 基本是没有问题的。forin 的时候判断下hasOwnProperty就ok了。基本 forin 都会判断的。

    放的位置么,把这些东西全部收集下放到代码最前面就可以了。

    至于上面说的改原型好还是当成一个函数。这个自己的项目无所谓。怎么喜欢怎么来就可以了。多人开发不推荐。至少如果要加的话应该大家统一明确觉得需要加才加。随意污染原型还是会出各种莫名奇妙的bug的。比如举个例子:
    比如 程序员1在 Object 上加一个 isArray 方法很常见吧。
    然后另一个程序员2写了个 forEach 函数,
    function forEach (objOrArray, callback, {isArray: false, context:}) {...}
    用最后一个参数的isArray 判断是循环数组还是forin。 最后一个参数可缺损。默认是false。(基本默认都是true。 但是我这边只是举个例子)

    那么这个如果缺损的时候 默认就都是true了。 而且这个bug很难debug。如果不知道程序员1有这样的代码的情况下。
    Mutoo
        8
    Mutoo  
       2014-05-09 11:12:48 +08:00
    @zythum 所以 underscore.js 这些库推荐把工具函数外部实现,而不是直接去修改原生对象。
    alsotang
        9
    alsotang  
       2014-05-09 11:16:05 +08:00
    js 里面一般都不推荐修改 prototype 的,用 underscore.string 试试?
    zythum
        10
    zythum  
       2014-05-09 11:20:32 +08:00   ❤️ 1
    @Mutoo
    这个处理 真心见人见智的。 我只是说业务里面不推荐去改原型。 对于类库而言api都是可知的。所以危险不大。
    现在处理全部污染原型的。 prototype, mooTools
    用原型补全IE等低级浏览器的 avalon
    不污染原型的 underscore之类的
    snoopy
        11
    snoopy  
       2014-05-09 12:58:10 +08:00   ❤️ 1
    还是不要这样做,用现成的库更好,不要忽视最佳实践,都是前人的经验教训。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5355 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 08:30 · PVG 16:30 · LAX 00:30 · JFK 03:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.