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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

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

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Q&A

解決済

3回答

2035閲覧

GASでアロー関数の書き方でmap関数の第2引数のオブジェクトをthisで用いたい

SkyRocket

総合スコア26

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

Google API

Googleは多種多様なAPIを提供していて、その多くはウェブ開発者向けのAPIです。それらのAPIは消費者に人気なGoogleのサービス(Google Maps, Google Earth, AdSense, Adwords, Google Apps,YouTube等)に基づいています。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

JavaScript

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

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

0グッド

0クリップ

投稿2022/12/29 02:57

編集2023/01/05 23:34

前提

Google Apps Script(GAS)でmapを用いて配列を操作するプログラムを作成しています。

アロー関数でmapの第2引数のオブジェクト(こちらでは配列)をthisで利用したいのですが、上手くできません。
従来の書き方では思うように出力されます。

実現したいこと

従来の書き方で記載したコードは次のソースコードです。

function myFunction01() { var wordlist = { 'あ': 1, 'い': 2, 'う': 3, 'え': 4, 'お': 5 }; var selectword = ['あ', 'い', 'う']; var result = selectword.map( function (value) { return this[value]; }, wordlist ); console.log(result); //出力結果:[ 1, 2, 3 ] }

アロー関数で記載すると以下になりますが、出力結果が意図したものではありません。

function myFunction02() { let wordlist = { 'あ': 1, 'い': 2, 'う': 3, 'え': 4, 'お': 5 }; let selectword = ['あ', 'い', 'う']; let result = selectword.map((value => this[value]), wordlist); console.log(result); //出力結果:[ undefined, undefined, undefined ] }

アロー関数で記載し、第2引数のオブジェクトをthisで利用したいです。
どのようなコードにしたら、宜しいか、どなたかご教示頂けますと助かります。

発生している問題・エラーメッセージ

アロー関数で第2引数のオブジェクトを利用できず、thisを使えない。出力結果が[ 1, 2, 3 ]にならない。

試したこと

以下のように第2引数を用いず、thisも用いなければ、出力されます。

function myFunction03() { let wordlist = { 'あ': 1, 'い': 2, 'う': 3, 'え': 4, 'お': 5 }; let selectword = ['あ', 'い', 'う']; let result = selectword.map((value => wordlist[value])); console.log(result); //出力結果:[ 1, 2, 3 ] }

補足情報(FW/ツールのバージョンなど)

参考サイト:
【JavaScript入門】配列処理をするmap()の使い方とMapオブジェクトの解説!
https://www.sejuku.net/blog/21812

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

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

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

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

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

think49

2022/12/30 06:47

let result = selectword.map((value => this[value]), wordlist); と書きたくない理由は何でしょうか。 出来ない事をやろうとしている場合、XY問題となります。 目的や背景を明らかにし、それに沿ったサンプルコードを出す必要があると思います。 https://ja.meta.stackoverflow.com/questions/2701/ 目的を想像して回答していますが、想像ありきの回答な為、最適解ではない可能性があります。
SkyRocket

2022/12/30 09:38

ご回答頂きありがとうございます。 >let result = selectword.map((value => this[value]), wordlist); >と書きたくない理由は何でしょうか。 分かりずらくて申し訳ございません。 「let result = selectword.map((value => this[value]), wordlist);」のように書きなくないのではなく、書きたいと思っています。書きたいが、書いた場合に「[ undefined, undefined, undefined ]」となってしまい、「[ 1, 2, 3 ]」とならないため困っている状態です。 Apps Scriptの画面で「let result = selectword.map(」と入力すると、mapについての説明が表示され、書くことができるように読み取れたのですが、上手く行かない為、悩んでいるためです。 ***** map(callbackfn: (value: string, index: number, array: string[]) => any, thisArg?: any): any[] A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array. Calls a defined callback function on each element of an array, and returns an array that contains the results. <翻訳> 最大 3 つの引数を受け入れる関数。 map メソッドは、配列内の要素ごとに callbackfn 関数を 1 回呼び出します。 配列の各要素に対して定義済みのコールバック関数を呼び出し、結果を含む配列を返します。 ***** このmapの説明は、従来の書き方に当てはまる説明で、アロー関数では通用しない書き方なのですかね。
think49

2022/12/31 13:43 編集

@SkyRocket さん すみません。2022/12/30 15:47の修正依頼では引用コードが間違っていました。 「下記コードではNGな理由は何でしょうか」が私が確認依頼した意図になります。 let result = selectword.map((value => wordlist[value]));
SkyRocket

2023/01/02 16:40

ご確認及びご回答頂きありがとうございます。 NGな理由についてですが、私の変なこだわりだと思います。 let result = selectword.map((value => wordlist[value])); と記載すれば、要件通りになったのですが、 map関数では第2オブジェクトを指定できるように説明書きされていましたが、 その通りにならない結果になったので、困っておりました。 他の方とやり取りさせていただき、 仕様上、私のコードでは難しいことが分かりました。 ありがとうございました。
guest

回答3

0

アロー関数で第2引数のオブジェクトを利用できず、thisを使えない。

アロー関数は、thisが書いた環境によって決まるのが仕様で、呼び出し方によって変えることはできません。

「第2引数を用いず、thisも用いない」形で書くしかありません。

投稿2022/12/29 08:10

maisumakun

総合スコア145121

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

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

SkyRocket

2022/12/30 08:57

ご回答頂きありがとうございます。
guest

0

ベストアンサー

this値の束縛

this値の束縛は「早いもの勝ち」です。
アロー関数でthis値を束縛した後に、Array.prototype.map()の第二引数でthis値を束縛し直すことはできません


ここでいう「束縛」とは「外部から関数コード内で使用する値を固定する挙動」を指します。
Function.prototype.bind() でも「this値を束縛」することが可能です。

例えば、下記2つのコードは等価です。

javascript

1'use strict'; 2const wordlist1 = {'あ': 1, 'い': 2, 'う': 3, 'え': 4, 'お': 5}; 3const wordlist2 = {'あ': 'a', 'い': 'b', 'う': 'c', 'え': 'd', 'お': 'e'}; 4 5(function () { 6 let selectword = ['あ', 'い', 'う']; 7 8 const result1 = selectword.map(value => this[value], wordlist1); 9 const result2 = selectword.map(function (value) { return this[value]; }.bind(wordlist2), wordlist1); 10 11 console.log(result1); // 出力結果:['a', 'b', 'c'] 12 console.log(result2); // 出力結果:['a', 'b', 'c'] 13}).call(wordlist2);

アロー関数はいったん忘れて、call, apply, bindあたりの挙動を追いかけてみると、見えるものがあるかもしれません。

javascript

1'use strict'; 2const sample = function sample () { console.log(this); }; 3sample.bind(1).call(2); // 1 4sample.bind(1).apply([3]); // 1

解決方法

質問文を素直に読めば、「従来の書き方で記載したコード」で解決できますが、

javascript

1let result = selectword.map((value => wordlist[value]));

この状況で、Array.prototype.map() の第二引数を指定しようとする理由がないので、実際のコードでは第一引数に指定すべき変数が別スコープにあるものと想像します。
結論としては、関数宣言か関数式で関数定義しましょう。

javascript

1'use strict'; 2const callbackfn = function callbackfn (value) { return this[value]; }; 3 4function myFunction03() { 5 let selectword = ['あ', 'い', 'う']; 6 let wordlist = { 7 'あ': 1, 8 'い': 2, 9 'う': 3, 10 'え': 4, 11 'お': 5 12 }; 13 let result = selectword.map(callbackfn, wordlist); 14 15 console.log(result); //出力結果:[ 1, 2, 3 ] 16} 17 18myFunction03();

投稿2022/12/30 06:36

編集2023/01/05 11:14
think49

総合スコア18156

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

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

SkyRocket

2022/12/30 09:32

ご回答頂きありがとうございます。 状況について、投稿内容について、別の言い方で再度お伝えいたします。 ##### Apps Scriptの画面で「let result = selectword.map(」と入力すると、mapについての説明が表示されます。 この説明の1行目に「thisArg?: any」と第2引数があります。 ***** map(callbackfn: (value: string, index: number, array: string[]) => any, thisArg?: any): any[] A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array. Calls a defined callback function on each element of an array, and returns an array that contains the results. <翻訳> 最大 3 つの引数を受け入れる関数。 map メソッドは、配列内の要素ごとに callbackfn 関数を 1 回呼び出します。 配列の各要素に対して定義済みのコールバック関数を呼び出し、結果を含む配列を返します。 ***** 前述した従来の書き方では次のように記載していました。 ----- var result = selectword.map( function (value) { return this[value]; }, wordlist ); ----- アロー関数の書き方で 「let result = selectword.map((value => this[value]), wordlist);」 のように記載すると、出力結果が 「[ undefined, undefined, undefined ]」となってしまうので、困っていました。 ##### 勉強不足で初歩的な質問となり恐縮です。 コメント頂いたコード(18行ある方)の書き方が、この私のコメント内の上部で記載した「mapについての説明」の使い方になるのでしょうか。 === map(callbackfn: (value: string, index: number, array: string[]) => any, thisArg?: any): any[] === の意味は、map関数の 第1引数が「callbackfn: (value: string, index: number, array: string[]) => any」で 第2引数が「thisArg?: any」で 最後の「: any[]」は”配列を扱う関数”と意味するのではないかと思っています。 また、頂いたコード大変勉強になりました。 頂いたコードでは、myFunction03を実行すると配列を設定し、「let result = selectword.map(callbackfn, wordlist);」に移動し、「const callbackfn = function callbackfn (value) { return this[value]; };」に移りますが、この「function callbackfn (value) 」の「value」は、「let result = selectword.map」の第1引数のvalueであり、「return this[value]」の「this」は、「map(callbackfn, wordlist);」のwordlistが該当しているのだと思いました。このような書いたことが少ないので、もし認識違いでしたらご指摘いただけますと幸いです。
maisumakun

2022/12/30 11:32

> コメント頂いたコード(18行ある方)の書き方が、この私のコメント内の上部で記載した「mapについての説明」の使い方になるのでしょうか。 何を疑問視されているのでしょうか。
SkyRocket

2022/12/31 01:38

ご確認頂きありがとうございます。 説明で以下のように表示される関数の使い方について、お聞きしたいと思いました。 ***** map(callbackfn: (value: string, index: number, array: string[]) => any, thisArg?: any): any[] ***** 以下のようにグローバルで定義することが一般的なのでしょうか。 ----- myFunction03関数内 > let result = selectword.map(callbackfn, wordlist); > console.log(result); //出力結果:[ 1, 2, 3 ] グローバル >'use strict'; >const callbackfn = function callbackfn (value) { return this[value]; }; ----- グローバルで「const callbackfn・・・」と定義しないで、 「let result = selectword.map((value => this[value]), wordlist);」(仮)のように 関数内で利用することは出来ないのでしょうか。 初歩的な質問でしたら申し訳ございません。
think49

2023/01/05 10:42 編集

@SkyRocket さん > コメント頂いたコード(18行ある方)の書き方が、この私のコメント内の上部で記載した「mapについての説明」の使い方になるのでしょうか。 すみませんが、「Apps Script」が出力するヘルプの意図についてまでは私は責任を持てません。 少なくとも、アロー関数が意図しない動きになる理由については、本回答の「this値の束縛」が回答になっていると思っています。 原理を理解した上で、ヘルプの解釈についてはご自身で判断をお願いします。 > グローバルで「const callbackfn・・・」と定義しないで、 > 「let result = selectword.map((value => this[value]), wordlist);」(仮)のように > 関数内で利用することは出来ないのでしょうか。 そのように書く目的は何でしょうか。 私がArray.prototype.map() の第二引数を指定する理由は、本回答に書いた通りですが、それ以外に何か具体的な理由があれば教えて下さい。 「目的」は「そのコードを書く必然性」と捉えてもいいと思います。 私は「目的」を始めに設定し、「要件」を作り、要件を満たすコードを書く、というやり方をします。 その過程で矛盾がないのであれば、それが自分にとっての良いコードだと思います。
SkyRocket

2023/01/02 16:32

ご確認及びご回答頂きありがとうございます! >私がArray.prototype.map() の第二引数を指定する理由は、本回答に書いた通りですが、それ以外に何か具体的な理由があれば教えて下さい。 自身の勉強不足であることを痛感致しました。 thisの束縛という情報が分からなかったため、 Googleで「アロー関数 this値 束縛」と調べたところ、ご教示頂いた内容がすこし理解できました。 アロー関数でのthisの取り扱いは難しいですね。 私のコードを改めて記載します。 >let result = selectword.map((value => this[value]), wordlist); 仰っていることは以下のことと思いました。 ※しかし、「>this値の束縛は「早いもの勝ち」です。アロー関数でthis値を束縛した後に、Array.prototype.map()の第二引数でthis値を束縛し直すことはできません」の「アロー関数でthis値を束縛した」がどの部分で束縛したか自信が持てませんでした。 ### 1.このコードの【let result = selectword.map((value => this[value】内にあるthisには「selectword.map(」のselectword配列オブジェクトが入る。(このように、最初にこのthisにセットされる。) 2.1のつづきの第2引数の【]), wordlist);】ではthisには既に1で入っているので、入れない。 ### 現時点で詳細を伺っても私の基礎が足りていないので、 お手を煩わせてしましそうです。勉強してまいります。 ありがとうございました。
think49

2023/01/05 11:11

@SkyRocket さん 遅くなりましたが、「束縛」の説明を本回答の「this値の束縛」に追記しました。
SkyRocket

2023/01/05 14:34 編集

ご確認頂きありがとうございます。 お陰さまで理解度が高まりました。 ※まだなんとなくですが、直前のやり取りよりは理解しました。 「下記2つのコード」とはコード内にある2つ(wordlist1とwordlist2の関連)ことですね。 次のように理解しました。 1.コードが実行される。 2.wordlist1、wordlist2で連想配列を設定する。 3.function関数を先に囲んでいるのが「.call(wordlist2);」である。   selectword 配列を設定した後に、   const result1 = selectword.map(value => this[value], wordlist1);   にある「this」は「.call(wordlist2);」の「wordlist2」である。   ※「selectword.map(value => this[value], wordlist1);」の第2引数の「wordlist1」    は既に「.call(wordlist2);」の「wordlist2」で設定されているので、設定できない。 4.「console.log(result1);」で「['a', 'b', 'c']」が出力される。 >例えば、下記2つのコードは等価です。 ■□■□■□■□■□■□■□■□■□■□ 'use strict'; const wordlist1 = {'あ': 1, 'い': 2, 'う': 3, 'え': 4, 'お': 5}; const wordlist2 = {'あ': 'a', 'い': 'b', 'う': 'c', 'え': 'd', 'お': 'e'}; (function () { let selectword = ['あ', 'い', 'う']; const result1 = selectword.map(value => this[value], wordlist1); const result2 = selectword.map(function (value) { return this[value]; }.bind(wordlist2), wordlist1); console.log(result1); // 出力結果:['a', 'b', 'c'] console.log(result2); // 出力結果:['a', 'b', 'c'] }).call(wordlist2); ■□■□■□■□■□■□■□■□■□■□ ちなみに試しに「}).call(wordlist2);」を「}).call(wordlist1);」に変えたところ、 [ 1, 2, 3 ] [ 'a', 'b', 'c' ] が表示されることも確認しました。 以下のコードは「sample.bind(1)」で1で設定した後に、「.call(2);」で2にしようとしても設定できない、という例えですね。 ■□■□■□■□■□■□■□■□■□■□ 'use strict'; const sample = function sample () { console.log(this); }; sample.bind(1).call(2); // 1 sample.bind(1).apply([3]); // 1 ■□■□■□■□■□■□■□■□■□■□ 大変勉強になりました!ありがとうございます。 追伸 コメント欄でコード枠を設けれなかったので、■□■線でコードを囲んでいます。
guest

0

アロー関数から見たthisはglobalThisと同義になります
おとなしく普通のfunctionを使いましょう

投稿2022/12/29 04:30

kinji2532

総合スコア57

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

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

SkyRocket

2022/12/30 08:57

ご回答頂きありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問