質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CoffeeScript

CoffeeScriptはプログラミング言語です。シンタックスシュガーの導入により、JavaScriptのコードに変換された後動作します。JavaScriptに比べ、可読性と簡潔性が向上しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

4回答

4128閲覧

coffeescriptからjavascriptのコンパイルでreturnが一つ余計に表示されてしまう。

s.k

総合スコア423

CoffeeScript

CoffeeScriptはプログラミング言語です。シンタックスシュガーの導入により、JavaScriptのコードに変換された後動作します。JavaScriptに比べ、可読性と簡潔性が向上しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

0クリップ

投稿2016/11/01 10:04

編集2016/11/02 03:30

私がフォローしている方々でcoffeescriptタグを持つ人にリクエストを送りました!

###前提・実現したいこと
処理速度、コードの複雑化を改善するためにjavascriptをcoffeescriptへ移行したい。
下記番号で言いますと、①=③になるように②のCoffeeScriptを修正したい。

javascriptでfacebookのような「続きを見る」機能を苦戦しながらもみなさんのご助力をいただき実装しました。この機能は複数ページに必要な機能でしたので、複数ファイルに同様のjsコードを記述しています。

しかし、
・同様のコードを書いているために無駄が多く見にくい。
・(これはご指摘を受けたのですが、)jsとrailsの接続をするという二度手間が生じる。

という問題がありますので、JavaScriptコードをCoffeeScriptコードに書き換えようと考えました。

###発生している問題・エラーメッセージ
問題はこのエラーです。

ExecJS::RuntimeError in Page#index Showing /home/ubuntu/workspace/app/views/layouts/application.html.erb where line #6 raised: SyntaxError: [stdin]:4:19: reserved word 'function'

このエラーは調べたところ、
coffee内のコードミスということでしたので、

http://coffeescript.org/

で、一字一句確認したのですが、1点だけどうしてもうまくいきません。
・元のjavascriptコードよりも});が一つ少ない。

###該当のソースコード

①【元のJavaScriptコード】
②【①のJavascriptコードを書き換えたCoffeeScriptコード】
③【http://coffeescript.org/で②のCoffeeScriptコードをコンパイルしたJavaScriptコード】

①【元のJavaScriptコード】

JavaScript

1$(document).ready(function() { 2 var showChar = 100; 3 var ellipsestext = "..."; 4 var moretext = "more"; 5 var lesstext = "less"; 6 $('.more').each(function() { 7 var content = $(this).html(); 8 9 if(content.length > showChar) { 10 11 var c = content.substr(0, showChar); 12 var h = content.substr(showChar, content.length - showChar); 13 14 var html = c + '<span class="moreellipses">' + ellipsestext+ '&nbsp;</span><span class="morecontent"><span>' + h + '</span>&nbsp;&nbsp;<a href="" class="morelink">' + moretext + '</a></span>'; 15 16 $(this).html(html); 17 } 18 19 }); 20 21 $(".morelink").click(function(){ 22 if($(this).hasClass("less")) { 23 $(this).removeClass("less"); 24 $(this).html(moretext); 25 } else { 26 $(this).addClass("less"); 27 $(this).html(lesstext); 28 } 29 $(this).parent().prev().toggle(); 30 $(this).prev().toggle(); 31 return false; 32 }); 33}); ←③で足りない箇所

②【①のJavascriptコードを書き換えたCoffeeScriptコード】

CoffeeScript

1$(document).ready -> 2 showChar = 100 3 ellipsestext = "..." 4 moretext = "more" 5 lesstext = "less" 6 return 7 8$('.more').each -> 9 content = $(trim).$(this).html() 10 11 if content.length > showChar 12 13 c = content.substr 0, showChar 14 h = content.substr showChar, content.length - showChar 15 16 html = c + '<span class="moreellipses">' + ellipsestext+ '&nbsp;</span><span class="morecontent"><span>' + h + '</span>&nbsp;&nbsp;<a href="" class="morelink">' + moretext + '</a></span>' 17 18 $(this).html html 19 return 20 21$(".morelink").click -> 22 if $(this).hasClass "less" 23 $(this).removeClass "less" 24 $(this).html moretext 25 return 26 else 27 $(this).addClass "less" 28 $(this).html lesstext 29 return 30 31 $(this).parent().prev().toggle() 32 $(this).prev().toggle() 33 false

③【http://coffeescript.org/で②のCoffeeScriptコードをコンパイルしたJavaScriptコード】

Javascript

1$(document).ready(function() { 2 var ellipsestext, lesstext, moretext, showChar; 3 showChar = 100; 4 ellipsestext = "..."; 5 moretext = "more"; 6 lesstext = "less"; 7}); 8 9$('.more').each(function() { 10 var c, content, h, html; 11 content = $(trim).$(this).html(); 12 if (content.length > showChar) { 13 c = content.substr(0, showChar); 14 h = content.substr(showChar, content.length - showChar); 15 html = c + '<span class="moreellipses">' + ellipsestext + '&nbsp;</span><span class="morecontent"><span>' + h + '</span>&nbsp;&nbsp;<a href="" class="morelink">' + moretext + '</a></span>'; 16 $(this).html(html); 17 } 18}); 19 20$(".morelink").click(function() { 21 if ($(this).hasClass("less")) { 22 $(this).removeClass("less"); 23 $(this).html(moretext); 24 return; 25 } else { 26 $(this).addClass("less"); 27 $(this).html(lesstext); 28 return; 29 } 30 $(this).parent().prev().toggle(); 31 $(this).prev().toggle(); 32 return false; 33}); ←下にもう一つ});が入るはず。

何卒、ご助言お願い致します。

###情報追加部分

④【現時点のCoffeeScriptコード】

CoffeeScript

1$ -> 2 showChar = 100 3 ellipsestext = "..." 4 moretext = "more" 5 lesstext = "less" 6 7 $('.more').each -> 8 content = $(@).html() 9 10 if content.length > showChar 11 12 c = content.substr 0, showChar 13 h = content.substr showChar, content.length - showChar 14 15 html = """ #{c} 16 <span class="moreellipses"> 17 #{ellipsestext}&nbsp; 18 </span> 19 <span class="morecontent"> 20 <span>#{h}</span>&nbsp;&nbsp; 21 <a href="" class="morelink">#{moretext}</a> 22 </span>""" 23 24 $(@).html html 25 26 $(".morelink").click -> 27 if $(@).hasClass "less" 28 $(@).removeClass "less" 29 $(@).html moretext 30 else 31 $(@).addClass "less" 32 $(@).html lesstext 33 34 $(@).parent().prev().toggle() 35 $(@).prev().toggle() 36 return false;

⑤【④をコンパイルしたJavaScriptコード】

JavaScript

1$(function() { 2 var ellipsestext, lesstext, moretext, showChar; 3 showChar = 100; 4 ellipsestext = "..."; 5 moretext = "more"; 6 lesstext = "less"; 7 $('.more').each(function() { 8 var c, content, h, html; 9 content = $(this).html(); 10 if (content.length > showChar) { 11 c = content.substr(0, showChar); 12 h = content.substr(showChar, content.length - showChar); 13 html = " " + c + "\n<span class=\"moreellipses\">\n" + ellipsestext + "&nbsp;\n</span>\n<span class=\"morecontent\">\n <span>" + h + "</span>&nbsp;&nbsp;\n <a href=\"\" class=\"morelink\">" + moretext + "</a>\n</span>"; 14 return $(this).html(html); 15 } 16 }); 17 return $(".morelink").click(function() { ←どうしてもこのreturnを消したい。 18 if ($(this).hasClass("less")) { 19 $(this).removeClass("less"); 20 $(this).html(moretext); 21 } else { 22 $(this).addClass("less"); 23 $(this).html(lesstext); 24 } 25 $(this).parent().prev().toggle(); 26 $(this).prev().toggle(); 27 return false; 28 }); 29});

⑥【実現したいJavaScriptコード】

Javascript

1$(document).ready(function() { 2 var ellipsestext, lesstext, moretext, showChar; 3 showChar = 100; 4 ellipsestext = "..."; 5 moretext = "more"; 6 lesstext = "less"; ←⑤でreturnをjsコードで追加したことで、coffeeではreturnが消えました。 7}); 8 9$('.more').each(function() { 10 var c, content, h, html; 11 content = $(trim).$(this).html(); 12 if (content.length > showChar) { 13 c = content.substr(0, showChar); 14 h = content.substr(showChar, content.length - showChar); 15 html = c + '<span class="moreellipses">' + ellipsestext + '&nbsp;</span><span class="morecontent"><span>' + h + '</span>&nbsp;&nbsp;<a href="" class="morelink">' + moretext + '</a></span>'; 16 $(this).html(html); 17 } 18}); 19 20$(".morelink").click(function() { 21 if ($(this).hasClass("less")) { 22 $(this).removeClass("less"); 23 $(this).html(moretext); 24 } else { 25 $(this).addClass("less"); 26 $(this).html(lesstext); 27 } 28 $(this).parent().prev().toggle(); 29 $(this).prev().toggle(); 30 return false; 31 }); 32});

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

参考情報

次の例を見てください。

$ cat a.coffee foo = (x) -> console.log x $ coffee -pb a.coffee var foo; foo = function(x) { return console.log(x); };
$ cat b.coffee foo = (x) -> console.log x return $ coffee -pb b.coffee var foo; foo = function(x) { console.log(x); };

投稿2016/11/03 15:11

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s.k

2016/11/04 02:28 編集

katoyさん ありがとうございます! 記事みました。 すべてを理解できはしなかったのですが、 ざっくりいうと、値を返さない関数にはreturnをつける。 returnをつけると無駄なコードを省き最適化されるといった具合でしょうか…
guest

0

なにやら色々混乱しているようですが…ひとつひとつ指摘していきます。

###CoffeeScriptはインデントがブロックになる。

CoffeeScript

1f -> 2 a() 3 4 b()

CoffeeScript

1f -> 2 a() 3 4b()

は違います。上ではb()はfの引数の無名関数の中に含まれていますが、下ではb()は無名関数の外側です。質問の①は上の構成である(全て関数の中にある)のに、②ではインデントされていないところがあるため、下の構成になっています。これでは同じになりません。JavaScriptをCoffeeScriptにする場合は、ブロックを構成する{}の対応通りに、インデントと逆インデントをしなければなりません。綺麗にインデントを整形しているJavaScriptであれば、そのJavaScriptとCoffeeScriptのインデントは同じになるはずです。しかし、**①と②では$('.more').each ...$(".morelink").clickのインデントが同じではありません。**だからブロックが全体で包まれず、最後の方のブロックを閉じる分が少なく見えるのです。

###CoffeeScriptでは最後の式を返す。
JavaScriptではreturn文がない場合、最後にreturn;があると見なされ、returnで式が指定されていない場合はundefinedを返します。逆に言うと、最後のreturn;は省略可能と言うことです。(他の言語と違って、JavaScriptでは何も返さない関数を作ることはできません)

対して、CoffeeScriptでは、最後に評価された式の結果を返します。つまり、最後が【何かの式】という形であれば、return 【何かの式】のようになっていると見なします。なお、CoffeeScriptではifやwhile等も文ではなく式ですので、必ず何かしらの値を返しますので、同じくreturnが付くことになります(ただし、式として評価するためにやや複雑なコードに変換されます)。

もし、JavaScriptでreturnを省略したときの動作と同じにしたいというのであれば、CoffeeScriptでは逆にreturn(ただし、何も指定しない)を省略せずに書く必要があります。つまり、CoffeeScriptは最後の式の結果を返す場合はreturnを省略でき、JavaScriptではundefinedを返す場合のみreturnを省略できるという逆の動作になっていると言うことです。

なお、CoffeeScriptのundefined変数はvoid 0であり、その結果としてundefinedになるだけです。JavaScriptにおいてreturn;return undefined;が同じではないのと同じく、CoffeeScriptではreturnreturn undefindは同じではありませんが、結果だけを見ると、CoffeeScriptは両方ともundefindを返すという同じ動作になります。

投稿2016/11/02 04:42

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s.k

2016/11/02 05:20

raccyさん おお… なるほど… JavaScriptとCoffeeScriptの違いの一つにインデントの指定があるのはわかったのですが、 具体的にインデントがどのように機能しているのかは理解し切れていませんでした。 returnに関しても同じです。 すっきりとした気分になりました。 ありがとうございます(^^)
guest

0

ベストアンサー

coffeeはsyntaxシュガーで
$(document).readyは

coffeescript

1$ ->

とかけます。この時indentはスペース二つでブロックスコープの範囲を設定します。なので関数の中に含めたいコードは全て
関数のindentからスペース二つずらす必要があります。
よってreadyにすべて含めたければ$('.more')と$(".morelink")およびその中身のindentをずらす必要があります。

慣れないうちは

coffeescript

1$ -> 2 console.log('test')

などから始めちょっとずつコードを付けたしながらやるのがいいと思います。

以下は補足情報になります。

returnは書かなくても関数のなかで最終評価された値を勝手に返しますが,明示的に付けても構いません。
returnで返り値を指定しないとvoid型の関数になるだけです。
単独の@はthisのエイリアスなのでthisの部分は@で書いたほうが見通し良くなります。

また,sprocketsを使っているとすべてのページでcoffeescriptが発火してしまうので特定のviewのみで使いたい場合はviewのbody内のdomのどこかに任意のid(ここではpage-idとします)を振っておき,

$ -> if $('#page-id').length>0 console.log('triggered in this page')

などとすることが多いです。
またcoffescriptは文字列展開とヒアドキュメント("""で囲む)(こちらはES6(''で囲む)でも使えるようになりましたが)が使えるので

javascript

1 html = c + '<span class="moreellipses">' + ellipsestext + '&nbsp;</span><span class="morecontent"><span>' + h + '</span>&nbsp;&nbsp;<a href="" class="morelink">' + moretext + '</a></span>'

coffeescript

1html = """ #{c} 2<span class="moreellipses"> 3 #{ellipsestext}&nbsp; 4</span> 5<span class="morecontent"> 6 <span>#{h}</span>&nbsp;&nbsp; 7 <a href="" class="morelink">#{moretext}</a> 8</span>""" 9

と書くと見通しが良くなると思います(compileしてないのでerror履いたら調べて補間してもらえうと)。

投稿2016/11/02 01:47

編集2016/11/02 02:12
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s.k

2016/11/02 03:34

tkowさん 返信ありがとうございます! tkowさんに教えていただいたコードをCooffeeScript(質問文の④)に書きました。 かなりコードがスッキリして見やすいです。 ただ、試行錯誤してもどうしてもreturnが一つ多く表示されてしまいます。(質問文の⑤) returnがある文の上か下のコードどちらに原因があるかご指摘いただけないでしょうか…
s.k

2016/11/02 03:52 編集

tkowさん ④のコードをそのまま、アプリファイルで実行したら正常に動きました! コンパイルしたときにreturnが余計にあるのにこれは一体…
退会済みユーザー

退会済みユーザー

2016/11/02 04:07 編集

coffeeScriptはそういう風にbuildされるものです。 javascriptのコードは汚くなったり冗長になりがちなのでcoffeeで管理してjsに自動でトランスパイルするような仕組みを作るものです。なので変換先のjavascriptが綺麗に生成されることを考慮していません。(元々プロダクトを作るときは結局uglifyするはずなのでコンパイル先の綺麗さは気にしなくていいという前提があります。) return の評価は戻り値が評価されてから起きるので,実行時に戻り値を受け取る変数がなくても問題は起きません。なのでこのように作成されるようになっています。 どうしても治したい場合はreturn false;の下に$(".morelink").clickの同じindentでreturn を入れてください。
退会済みユーザー

退会済みユーザー

2016/11/02 04:12

開発でjavascriptしか使えない方を考慮している感じですかね。 そうするとcoffeeの導入は良くないかもしれません。 typescriptはほぼes6そのままのコードを書けるのでこちらの方がいいと思います。
s.k

2016/11/02 04:26

returnの件、解決いたしました! ありがとうございます。 いっぱいあるのですね… typescript調べてみます^o^ 助かりました。 引き続き開発を続けたいと思います!
guest

0

$(document).ready は下記コードで完結している為、SyntaxError は発生しないように読めます。

JavaScript

1$(document).ready(function() { 2 var ellipsestext, lesstext, moretext, showChar; 3 showChar = 100; 4 ellipsestext = "..."; 5 moretext = "more"; 6 lesstext = "less"; 7});

CoffeeScript に詳しくありませんが、インデントに問題があるのではないでしょうか。

Re: s.k さん

投稿2016/11/01 10:11

編集2016/11/01 10:12
think49

総合スコア18156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s.k

2016/11/01 10:14

think49さん 先程はありがとうございました! 今、確認してみます!
think49

2016/11/01 10:20

本題とは関係ありませんが、$(".morelink").click(function() { 内の if, else でなぜ return しているのでしょうか。 元のJavaScriptコードにはない命令でそれがある為に $(this).parent().prev().toggle(); 以降のコードが絶対に通過しない文になってしまっています。
s.k

2016/11/01 10:40 編集

追記をしました。 最初にjsコードを修正した際に、returnがあちこちにありました。 調べたところ、returnがないところにはreturnのみを追加して明示的に示さなければならないと書いてあったので、いらぬところにreturnが書かれているという状況です… returnが修正したコードに存在していても最終的にcoffeescriptに出力されているコードが元のjsコードと一致していれば問題はないのかなと考えました! それと、そもそも、 $(document).ready(function() { var ellipsestext, lesstext, moretext, showChar; showChar = 100; ellipsestext = "..."; moretext = "more"; lesstext = "less"; }); この文に});はついていないので、これもエラーだと思います。 見逃していました…
think49

2016/11/01 10:55

すみませんが、コードが分散していて現状のまとめとなるコードが想像できません。 修正版を追記するなら部分的ではなく、全て追記して下さい。下記3つがあれば十分です。 - 元々のJavaScriptコード - CoffeeScriptコード - コンパイル後のJavaScriptコード 「①【元のjsコード】」が基本でCoffeeScriptでコンパイルしたら「①【元のjsコード】」が出力される動作を期待している、という理解でいいのでしょうか。 CoffeeScriptはインデントによって対応する括弧を決める言語のようです。 ということは、$('.more').each, $(".morelink").click のインデントを修正する必要がありますね。
s.k

2016/11/01 11:26 編集

think49さん、失礼しました! 気を付けます。 - 元々のJavaScriptコード  →①です。 - CoffeeScriptコード →②です。 - コンパイル後のJavaScriptコード →③です。 ④~⑥は①~③の具体的なエラー箇所と解決策のコードを書いたつもりです… わかりづらいですね。 コード左上に言語も追加します。 ‐‐「①【元のjsコード】」が基本でCoffeeScriptでコンパイルしたら「①【元のjsコード】」が出力される動作を期待している、という理解でいいのでしょうか。 はい!そうです。ですので、①=③という形にしたいです。 ‐‐CoffeeScriptはインデントによって対応する括弧を決める言語のようです。 ということは、$('.more').each, $(".morelink").click のインデントを修正する必要がありますね →そうなんですか。今試してみます! わかりづらいところがあれば全て言ってください! お手数おかけします。 自分でも質問文を修正し直してみます
s.k

2016/11/01 11:27 編集

上記コメントの - 元々のJavaScriptコード - CoffeeScriptコード - コンパイル後のJavaScriptコード ですが、間違えて伝えてしまいましたので修正しました。 少々お待ちください。 質問文も修正します。
s.k

2016/11/01 11:39

質問文の修正終了しました!
think49

2016/11/01 11:52

return は余計な位置でつけなくて良いようです。やはり、インデントが問題っぽいですね。
s.k

2016/11/01 12:37

ありがとうございます! returnを消して、インデント確かめてみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問