V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
vonnyfly
V2EX  ›  JavaScript

这个函数里的... 是什么东西,这么神奇,还有函数声明后面的{}。

  •  
  •   vonnyfly · 2016-05-05 11:22:21 +08:00 · 4284 次点击
    这是一个创建于 3130 天前的主题,其中的信息可能已经有所发展或是发生改变。
    export function create(styles: Object): {[name: string]: number} {
      const platformStyles = {};
      Object.keys(styles).forEach((name) => {
        let {ios, android, ...style} = {...styles[name]};
        if (ios && Platform.OS === 'ios') {
          style = {...style, ...ios};
        }
        if (android && Platform.OS === 'android') {
          style = {...style, ...android};
        }
        platformStyles[name] = style;
      });
      return StyleSheet.create(platformStyles);
    }
    
    25 条回复    2016-06-17 11:38:07 +08:00
    ayaseangle
        1
    ayaseangle  
       2016-05-05 11:28:48 +08:00 via Android
    annotation ?
    koi
        2
    koi  
       2016-05-05 11:30:45 +08:00
    这是 react native 里面的代码吧? react native 貌似用的不是原生的 js 而是 flow.js? 类似 typescript 之类的
    plantain
        3
    plantain  
       2016-05-05 11:44:36 +08:00 via Android
    第一个是 es6 的 rest parameter ,第二个是一个类型,函数返回值的类型。
    plantain
        4
    plantain  
       2016-05-05 11:47:11 +08:00 via Android
    那个类型里定义了一个 es6 的 computed property
    rogerchen
        5
    rogerchen  
       2016-05-05 11:51:47 +08:00 via Android
    ...是 destructuring
    函数声明后边那个{}是返回值类型声明
    这段代码就是 typescript
    iugo
        6
    iugo  
       2016-05-05 12:20:48 +08:00
    @plantain 这段代码中的用法应被称作 spread 而不是 rest. 是展开而不是集合.

    而且这是还未定型的 ES7 的特性.
    broadliyn
        7
    broadliyn  
       2016-05-05 12:39:54 +08:00
    醉了,越来越搞不懂 js 要干嘛了。。。。
    adspe
        8
    adspe  
       2016-05-05 12:44:55 +08:00
    @rogerchen 看到有类型指定就是 TS 了呀。 ES6 的 destructuring 和 spread 一起很好用
    visonme
        9
    visonme  
       2016-05-05 12:45:52 +08:00
    @broadliyn 不是 js 要干嘛,是那些公司,团体,个人相对 js 干点啥~ 呵呵~
    am241
        10
    am241  
       2016-05-05 12:48:09 +08:00 via Android
    js 算不算常见语言里语法最奇怪的?感觉已经远超 perl 了
    learnshare
        11
    learnshare  
       2016-05-05 12:58:16 +08:00
    TypeScript 吧,不过语法还是 ES6/2015/***
    secondwtq
        12
    secondwtq  
       2016-05-05 13:51:11 +08:00
    @am241 JS 语法感觉还行,但是有一些奇怪的机制。
    vonnyfly
        13
    vonnyfly  
    OP
       2016-05-05 14:03:26 +08:00
    @ayaseangle
    @koi
    @plantain
    @rogerchen
    @iugo
    @adspe
    的确是 TypeScript,刚刚看了下语法,发现 JS 的写法越来越逆天了。
    这里有 RN javascript 的特殊语法,大概能看懂,自己写有点难: https://facebook.github.io/react-native/docs/javascript-environment.html#javascript-syntax-transformers
    vonnyfly
        14
    vonnyfly  
    OP
       2016-05-05 14:05:53 +08:00
    三个点叫做 object spread syntax 。
    haozhang
        15
    haozhang  
       2016-05-05 14:09:22 +08:00 via iPhone
    @iugo spread 是 ES6 的吧,怎么会是 ES7 的呢
    fds
        16
    fds  
       2016-05-05 14:12:54 +08:00
    其实就是为了写起来方便,简化字典操作。
    Phariel
        17
    Phariel  
       2016-05-05 14:16:23 +08:00 via Android
    js 有赶超 ruby 的趋势
    vonnyfly
        18
    vonnyfly  
    OP
       2016-05-05 14:20:20 +08:00
    @haozhang object spread 是 ES7 , Array/call spread 是 ES6 ,应该是这样的。
    vonnyfly
        19
    vonnyfly  
    OP
       2016-05-05 14:21:28 +08:00
    @Phariel 在语法上跟 Ruby 元编程技巧有的一拼了。
    xjp
        20
    xjp  
       2016-05-05 21:05:08 +08:00
    typeScript js 的一个超集 现在非常流行

    上面这些语法什么的 js 暂时还不支持 之后会支持的
    frogcjn
        21
    frogcjn  
       2016-05-16 01:48:28 +08:00
    @vonnyfly 这个代码是哪里的? TypeScript 还没支持这个 ES8 object property spread and rest 的特性吧? TypeScript 2.1 才有。 https://github.com/Microsoft/TypeScript/wiki/Roadmap
    frogcjn
        22
    frogcjn  
       2016-05-22 01:09:15 +08:00
    @vonnyfly 这个应该是 babel+typeflow,
    babel-cli 再加上 babel-preset-es2015 ,和 babel-plugin-transform-object-rest-spread 这个插件。
    http://babeljs.io/docs/plugins/transform-object-rest-spread/

    TypeScript 还不支持 object property spread and rest.
    keyanzhang
        24
    keyanzhang  
       2016-06-11 15:32:16 +08:00
    不知道现在回复是否支持 Markdown 了,如果不支持的话请看上面的 gist 。

    这段代码应该来自 https://github.com/fbsamples/f8app/blob/master/js/common/F8StyleSheet.js

    `...` 是通过 [babel]( http://babeljs.io/) 转译的 Rest/Spread 。具体请看 https://github.com/sebmarkbage/ecmascript-rest-spread
    - `let {ios, android, ...style} = obj` 可以理解成 `let ios = obj.ios; let android = obj.android; let style = "obj 中除去 ios 和 android 之外的所有 property";`
    - `let` 右侧的 `{...styles[name]}` 可以理解成 `Object.assign({}, styles[name]);`
    - 同理,`style = {...style, ...android};` 会被 babel 转译成 `style = Object.assign({}, style, android);`

    函数签名中的 `: Object` 以及 `: {[name: string]: number}` 是 [flow]( https://flowtype.org/) 的类型标注(并不是 TypeScript )。换句话说,`create` 这个函数接受一个类型为 `Object` 的参数 `styles`,并返回一个类型为 `{[name: string]: number}` 的值。
    - 除去 `number`、`string`、`boolean`、`null` 以及 `undefined` 之外的任何类型均可被标注为 `Object`
    - https://flowtype.org/docs/objects.html#the-object-type
    - `{[name: string]: number}` 代表这是一个从 `string` 到 `number` 的映射。举个例子的话,这个函数返回 `{ a: 12, b: 13 }` 是没有问题的,但如果返回 `{ a: 12, b: 'foo' }` 则会报错,因为 `'foo'` 是一个 `string` 而不是 `number`
    - https://flowtype.org/docs/objects.html#objects-as-maps
    vonnyfly
        25
    vonnyfly  
    OP
       2016-06-17 11:38:07 +08:00
    @keyanzhang 写的很好。
    其实已多年看代码的经验就明白,只是觉得写的很神奇。
    赞你的解释。让我更清楚了语法相关的内容。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3514 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 04:40 · PVG 12:40 · LAX 20:40 · JFK 23:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.