payload: {"action":"created","issue":{"url":"https://api.github.com/repos/lzlu/Blog/issues/3","repository_url":"https://api.github.com/repos/lzlu/Blog","labels_url":"https://api.github.com/repos/lzlu/Blog/issues/3/labels{/name}","comments_url":"https://api.github.com/repos/lzlu/Blog/issues/3/comments","events_url":"https://api.github.com/repos/lzlu/Blog/issues/3/events","html_url":"https://github.com/lzlu/Blog/issues/3","id":287151122,"node_id":"MDU6SXNzdWUyODcxNTExMjI=","number":3,"title":"Optional Chaining Operator in JavaScript（JS的可选链操作符）","user":{"login":"lzlu","id":8563082,"node_id":"MDQ6VXNlcjg1NjMwODI=","avatar_url":"https://avatars2.githubusercontent.com/u/8563082?v=4","gravatar_id":"","url":"https://api.github.com/users/lzlu","html_url":"https://github.com/lzlu","followers_url":"https://api.github.com/users/lzlu/followers","following_url":"https://api.github.com/users/lzlu/following{/other_user}","gists_url":"https://api.github.com/users/lzlu/gists{/gist_id}","starred_url":"https://api.github.com/users/lzlu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lzlu/subscriptions","organizations_url":"https://api.github.com/users/lzlu/orgs","repos_url":"https://api.github.com/users/lzlu/repos","events_url":"https://api.github.com/users/lzlu/events{/privacy}","received_events_url":"https://api.github.com/users/lzlu/received_events","type":"User","site_admin":false},"labels":[{"id":799596268,"node_id":"MDU6TGFiZWw3OTk1OTYyNjg=","url":"https://api.github.com/repos/lzlu/Blog/labels/%E7%BF%BB%E8%AF%91","name":"翻译","color":"20e884","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2018-01-09T16:32:59Z","updated_at":"2019-10-17T03:39:12Z","closed_at":null,"author_association":"OWNER","body":"翻译自[Optional Chaining Operator in JavaScript – Bene Studio](https://blog.benestudio.co/optional-chaining-operator-in-javascript-342082de2db)\r\n\r\n![image](https://user-images.githubusercontent.com/8563082/34731577-aac5b328-f59d-11e7-8731-7f03d9fffd62.png)\r\n\r\n\r\n## 访问对象属性的问题\r\n我们经常会遇到一个问题，当我们想要去访问一个对象的属性时候却得到undefined或null。\r\n```\r\nvar user = { name: 'Joe' }\r\nvar zip = user.address.zip // ⚡⚡⚡\r\nUncaught TypeError: Cannot read property 'zip' of undefined\r\n```\r\n上面这个例子，我们希望访问到user.address.zip，但因为某种原因，user对象丢失了adress属性。\r\n## 解决方案#1:逻辑表达式\r\n```\r\nvar user = { name: 'Joe' }\r\nvar zip = user\r\n       && user.address\r\n       && user.address.zip\r\n```\r\n有点累赘和冗余\r\n## 解决方案#2:三元表达式\r\n```\r\nvar user = { name: 'Joe' }\r\nvar zip =\r\n  user === undefined\r\n  ? undefined\r\n  : user.address === undefined\r\n    ? undefined\r\n    : user.address.zip\r\n```\r\n更加累赘和冗余。\r\n## 解决方案#3:Try-Catch\r\n```\r\nvar user = { name: 'Joe' }\r\nvar zip\r\ntry {\r\n  zip = user.address.zip\r\n} catch (error) {\r\n  zip = null\r\n}\r\n```\r\n这样写会破坏对代码的控制，而且也有点累赘。\r\n当然还有很多方法和类库（比如[lodash.get](https://lodash.com/docs/4.17.4#get)）可以解决这类问题。\r\n# 可选链操作符（Optional Chaining Operator）\r\nECMA有个关于[Optional Chaining](https://claudepache.github.io/es-optional-chaining/)新提案，\r\n一共有stages 4，目前正处于stage 1。\r\n**其实这个语法，是借鉴(抄)了Ruby/Swift/C#的。当然TypeScript也是支持这个语法的，TS大法好！**\r\n```\r\nvar user = { name: 'Joe' }\r\nvar zip = user?.address?.zip\r\n```\r\nzips是undefined不会报错了。\r\n当然也支持function和constructor的写法。\r\n```\r\nvar address = getAddressByZip.?(12345)\r\n```\r\n如果调用时getAddressByZip是函数，则调用getAddressByZip(12345)，其他情况都被认为是undefined\r\n## 配置babel\r\n我们需要安装Babel的alpha7版本\r\n```\r\nnpm install --save-dev babel-cli@7.0.0-alpha.19\r\nnpm install --save-dev babel-plugin-transform-optional-chaining@^7.0.0-alpha.13.1\r\n\r\n```\r\n在根目录创建.babelrc文件\r\n```\r\n{\r\n  \"plugins\": [\"transform-optional-chaining\"]\r\n}\r\n\r\n```\r\n创建一个index.js，测试下。\r\n```\r\nvar user = { name: 'Joe' }\r\nvar zip = user?.address?.zip\r\nconsole.log(zip)\r\n```\r\n运行下：\r\n```\r\nnode_modules/.bin/babel-node index.js\r\n```\r\n或者编译一下：\r\n```\r\nnode_modules/.bin/babel index.js\r\n```\r\n## 编译后的代码\r\n编译后的index.js\r\n```\r\nvar _user$address;\r\nvar user = {\r\n  name: 'Joe'\r\n};\r\nvar zip =\r\n  user == null\r\n  ? void 0\r\n  : (_user$address = user.address) == null\r\n    ? void 0\r\n    : _user$address.zip;\r\nconsole.log(zip);\r\n```\r\nbabel编译后嵌套了三元表达式，像解决方案2。最主要的区别是优化了一些边缘情况。\r\n# 参考\r\n[Safe navigation operator - Wikipedia](https://en.wikipedia.org/wiki/Safe_navigation_operator)\r\nhttps://github.com/claudepache/es-optional-chaining\r\n[js中有没有什么库能安全的对对象属性进行访问 比如a.b.c.d？ - 知乎](https://www.zhihu.com/question/63738559)\r\n#前端"},"comment":{"url":"https://api.github.com/repos/lzlu/Blog/issues/comments/542984774","html_url":"https://github.com/lzlu/Blog/issues/3#issuecomment-542984774","issue_url":"https://api.github.com/repos/lzlu/Blog/issues/3","id":542984774,"node_id":"MDEyOklzc3VlQ29tbWVudDU0Mjk4NDc3NA==","user":{"login":"kmvan","id":3839554,"node_id":"MDQ6VXNlcjM4Mzk1NTQ=","avatar_url":"https://avatars0.githubusercontent.com/u/3839554?v=4","gravatar_id":"","url":"https://api.github.com/users/kmvan","html_url":"https://github.com/kmvan","followers_url":"https://api.github.com/users/kmvan/followers","following_url":"https://api.github.com/users/kmvan/following{/other_user}","gists_url":"https://api.github.com/users/kmvan/gists{/gist_id}","starred_url":"https://api.github.com/users/kmvan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kmvan/subscriptions","organizations_url":"https://api.github.com/users/kmvan/orgs","repos_url":"https://api.github.com/users/kmvan/repos","events_url":"https://api.github.com/users/kmvan/events{/privacy}","received_events_url":"https://api.github.com/users/kmvan/received_events","type":"User","site_admin":false},"created_at":"2019-10-17T03:39:12Z","updated_at":"2019-10-17T03:39:12Z","author_association":"NONE","body":"> VSCode 关掉 typescript 检查，只用 ESLint 就搞定了\r\n\r\n是肿么关掉的？"}}
other: {"actor":{"display_login":"kmvan"}}