LoginSignup
2
4

More than 5 years have passed since last update.

Rubyist が Javascripter になり始めてやらかしたこと (備忘録)

Posted at

概要

Electronアプリ開発に祭して、Javascriptを本格的に書くようになってから半年経ちました。

Railsアプリを書くことはあっても、view側のJSを本格的に書くことはありませんでした。

(その他もLambdaで少々...といったくらい)

Rubyistならではのハマり所って実は結構あるのでは?と思い、備忘録的に残しておくことにします。

※ どちらの言語がいいという話ではありません。

先に言語仕様を確認しておけば良いという話ではあります。

違いが面白かったりまどろっこしかったり、楽しんだ記録になります。

言語歴

  • Ruby : 9年目
  • Javascript : 1年目 (半年)
  • その他
    • Python 2.x (数ヶ月)
    • Erlang (数ヶ月)
    • C (大学で少々レベル)

以下、多分一度はやったやつ

最初にやるやつ

  • == で比較する
  • ; を書かない
  • 関数定義の引数部分に () を付けない, {} 閉じ忘れる
  • 関数の呼び出しに () を付けない
  • 関数の引数の数が幾つでも良い(0個でもいい)
  • const, let を書かない (& varのスコープでハマる)
  • ついついスネークケースで名前付け

Return を書かない

最後の評価値が返ることが身に染み付いてしまっている。

undefined になっていることに気づくのはテストを書いたときか、動かしてからか...。

def hoge
  "hogehoge"
end

hoge  #=> "hogehoge"
function hoge() {
  "hogehoge";
};

hoge();  //=> undefined

可変長引数

* がない!とならないように。

def func(*args)
  p args  #=> ["a", "b", "c"]
end
func('a', 'b', 'c')
function func(...args) {
  console.log(args)
}
func('a', 'b', 'c')  //=> [ 'a', 'b', 'c' ]

callbackがやたら気持ち悪く感じる

常時 lambda を渡しているような感じがする。

rubyの感覚的にはこんな感じ。まどろっこしく感じる。

class Array
  def forEach(func)
    self.each do |n|
      func.call(n)
    end
  end
end

[1, 2, 3].forEach(lambda {|n|
  puts n
})
[1, 2, 3].forEach((n) => {
  console.log(n);
});

this でやらかす

例は forEach 。jsの this は要注意。

class Foo
  def three; 3; end

  def bar
    [1, 2, 3].each do |n|
      puts n * self.three  #=> 3, 6, 9
    end
  end
end

Foo.new.bar
class Foo {
  three() { return 3; };

  bar() {
    /*
    [1, 2, 3].forEach(function(n) {
      console.log(n * this.three());  //=> TypeError: Cannot read property 'three' of undefined
    });
    */

    // 関数式にthisを指定する
    [1, 2, 3].forEach(function(n) {
      console.log(n * this.three());  //=> 3, 6, 9
    }, this);

    // アロー関数を使う
    [1, 2, 3].forEach(n => {
      console.log(n * this.three());  //=> 3, 6, 9
    });
  }
}

(new Foo).bar()

sleepが書きたいんだ!

ただし Promise にして待たないと意味はないので2度やらかす。

sleep(3)
setTimeout(() => {}, 3000);

非同期なにそれ

その Promise の話。

非同期関数の戻り値が Promise であることを忘れる or 知らない。

(setTimeoutをどう待てばいいんだ?でみんな一度は手を止めるのでは...?)

class Baz {
  asyncMyFunc() {
    return new Promise(resolve => {
      setTimeout(() => { resolve("qux");  }, 3000);
    });
  };

  async qux() {
    let val = this.asyncMyFunc();
    console.log(val);  // => Promise { <pending> }

    let val2 = await this.asyncMyFunc();
    console.log(val2);  // => "qux"
  };
};

(new Baz).qux();

await を知らないために callback 地獄へ

これが噂に聞く...という状態だった。

foo().then(result => {
  bar().then(result => {
    baz().then(result => {
      // ...
    });
  });
});
let result
result = await foo()
result = await bar()
result = await baz()

async と await の書き方に慣れない

awaitasync function のなかに書ける。

async function を await するように思ってしまうがそうじゃない。

async function piyo() {
  await asyncFunc()
}
piyo()

モンキーパッチ書きたいんだ!

ちょっとした時に。

先ほどの Foo#three() を書き換える例。

Foo.new.three  #=> 3
class Foo
  def three; "3"; end
end
Foo.new.three  #=> "3"

(new Foo).three();  //=> 3
Foo.prototype.three = function() { return "3" };
(new Foo).three();  //=> "3"

rspec -> mocha 書きたいんだ!

  • subject , is_expected 等々はなさそう
const expect = require('chai').expect
describe('Foo', () => {
  beforeEach(() => {
    // ...
  })
  let foo = new Foo

  describe('#hoge()', () => {
    it ('return "hogehoge"', () => {
      expect(foo.hoge()).to.equal("hogehoge");
    });
  });

  // 非同期関数のテスト
  describe('#fuga()', () => {
    it ('return "hogehoge"', async () => {
      expect(await foo.fuga()).to.equal("fugafuga");
    });
  });

  // shared_example 的に使える
  function piyo() {
    it ('return "piyopiyo"', () => {
      expect(Foo.piyo()).to.equal("piyopiyo");
    });
  };

  describe('#piyo()', piyo);

  context('when ...', () => {
    // ...
  });
});
$ ./node_modules/.bin/mocha 


  Foo
    #hoge()
      ✓ return "hogehoge"
    #fuga()
      ✓ return "hogehoge" (1006ms)
    #piyo()
      ✓ return "piyopiyo"


  3 passing (1s)


その他、今後も思い出したり出会い次第追記予定です。

2
4
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
2
4