LoginSignup
7
8

More than 5 years have passed since last update.

Universal JSで注意すべきJS/Node.jsの違い

Last updated at Posted at 2017-07-17
1 / 11

Universal JS

  • JavaScript/Node.jsは、同じ言語なのでClient/Server Sideでコードを共有可能
    • Validationなど共有可能
  • けれど各moduleのAPIの仕様は必ずしも一致しない
    • 仕様がどこにあるか、を知ることが重要

Q. JavaScriptのTimer APIの仕様はどこにあるでしょう?


A. whatwg

  • "setTimeout"と検索
  • MDN/MSDNなどが上位にくるので開く
    • 片方しかない場合は、vendorがそのAPIを独自実装している可能性
  • vendorがspec決めてる?
    • ex, MDNなら「仕様」とい う欄があるのでそこのリンクを辿ると......
  • whatwgが決めていた
    • w3c/whatwgはDOM(html等も含む)の仕様を定義
      • ただしvendorが従っている保証はない
    • EcmaはJSのruntimeのみ定義

Q. JSとNode.jsのTimer APIとでは仕様に違いがありますか?


A. JSとNode.jsのTimer APIの違い

  • returnの型
    • JSはID(number)
    • Node.jsはTimeout obj
      • timeout.ref(), timeout.unref()という便利な関数がある
  • setImmediate API
    • 各種ベンダーの内、MSのみdraftを定義
    • Node.jsも同時期に開発したがspecが全然違う
  • setTimeout(() => console.log('ok'), 0)

Q. JavaScriptのConsole APIの仕様はどこにあるでしょう?


A. draft段階(標準化されてない)


Q. Node.jsとEcmaScriptとで、Errorの仕様に違いはありますか?


A. あります

Errorオブジェクトのプロパティの観点で違いをみてみる

  • ECMAScript 2015: Error の定義
    • Error.prototype
    • Error.prototype.constructor
    • Error.prototype.message
    • Error.prototype.name
    • Error.prototype.toString()
  • Node独自の追加
    • error.code
    • error.errno
    • error.syscall
    • stack系はdocに書かれている通りv8独自の追加
  • ベンダー独自の拡張(非標準)
    • Error.prototype.description (MS)
    • Error.prototype.number (MS)
    • Error.prototype.fileName (Mozilla)
    • Error.prototype.lineNumber (Mozilla)
    • Error.prototype.columnNumber (Mozilla)
    • Error.prototype.stack (Mozilla/v8)
    • Error.captureStackTrace (v8)
    • Error.stackTraceLimit (v8)

Node.jsのmodule固有のError property

以前は記載がなかったので、Node.jsのdocにPRしました
https://github.com/nodejs/node/pull/10986

module property
net/http(s) error.address
net/http(s) error.port
fs error.path
// with `path` property
$node -e "require('fs').readFile('a file that does not exist', (err, data) => { console.error(err); });"
{ Error: ENOENT: no such file or directory, open 'a file that does not exist'
    at Error (native)
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: 'a file that does not exist' }

// with `address` and `port` property
$node -e "require('net').connect({port: 100}).on('error', (err) => { console.error(err); });"
{ Error: connect ECONNREFUSED 127.0.0.1:100
    at Object.exports._errnoException (util.js:1022:11)
    at exports._exceptionWithHostPort (util.js:1045:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1087:14)
  code: 'ECONNREFUSED',
  errno: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 100 }

// with `address` property (without `port` property)
$node -e "require('net').connect({host: 'localhost'}).on('error', (err) => { console.error(err); });"
{ Error: connect EADDRNOTAVAIL 127.0.0.1 - Local (0.0.0.0:54881)
    at Object.exports._errnoException (util.js:1022:11)
    at exports._exceptionWithHostPort (util.js:1045:20)
    at connect (net.js:881:16)
    at net.js:1010:7
    at GetAddrInfoReqWrap.asyncCallback [as callback] (dns.js:62:16)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:81:10)
  code: 'EADDRNOTAVAIL',
  errno: 'EADDRNOTAVAIL',
  syscall: 'connect',
  address: '127.0.0.1' }
7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8