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

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

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

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

Q&A

解決済

3回答

266閲覧

callの使い方を教えてください

takane

総合スコア63

JavaScript

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

0グッド

2クリップ

投稿2017/10/10 00:32

こんにちは。私はJavascriptを勉強しています。大体4ヶ月めです。

今callの使い方を学んでいるのですが、いまひとつしっくりと理解できません。

簡単にいえば、call()内の関数でオブジェクトを操作するというものだと思いましたが、下記の用に少し難易度の高いものを見ると意味がわからなくなってしまいます。

js

1// スーパークラス的な携帯電話 2function CellPhone(number) { 3 this.phoneNumber = number; 4} 5 6// サブクラス的なスマートフォン 7function SmartPhone(number, wifispots) { 8 this.wifispots = wifispots; 9 CellPhone.call(this, number); 10} 11SmartPhone.prototype = new CellPhone(); // insatnceof用 12 13// 利用コード(携帯番号とWifiスポットを固有データとして持たせます) 14var myphone = new SmartPhone('09012344432', ['Home','StarBucksWifi']);

上のコードを解説しながらcallというものは何をするものなのか教えて下さる方はいませんでしょうか?

よろしくおねがいいたします。

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

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

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

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

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

guest

回答3

0

.callは、「thisを設定してメソッドを呼ぶ」ための手法です。

SmartPhoneCellPhoneを継承する」というには、SmartPhoneのインスタンスもCellPhoneとして初期化する必要があります。そのため、SmartPhoneのコンストラクタからCellPhone.call(this)とすることで、自身に対してCellPhoneとしての初期化を実行しています。


なお、ES6ではclass構文が登場しているので、callやプロトタイプを駆使して継承を組み立てる必要は薄くなっています。

javascript

1class CellPhone{ 2 constructor(number) { 3 this.phoneNumber = number; 4 } 5} 6 7class SmartPhone extends CellPhone{ 8 constructor(number, wifispots) { 9 super(number); 10 this.wifispots = wifispots; 11 } 12}

投稿2017/10/10 02:08

maisumakun

総合スコア145183

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

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

takane

2017/10/10 04:31

ほかの方法もあるのですね。 まだ初心者のうちなので古い方法から学んでいこうとおもいます。 ありがとうございます。
guest

0

ベストアンサー

javascript

1function CellPhone(number) { 2 this.phoneNumber = number; 3} 4function SmartPhone(number, wifispots) { 5 this.wifispots = wifispots; 6 CellPhone.call(this, number); 7} 8martPhone.prototype = new CellPhone();

↑これは↓これと大体等価です。

javascript

1function CellPhone(number) { 2 this.phoneNumber = number; 3} 4function SmartPhone(number, wifispots) { 5 this.wifispots = wifispots; 6 this.phoneNumber = number; 7} 8martPhone.prototype = new CellPhone();

なぜ例文のような書き方をするかというと、

javascript

1function CellPhone(number) { 2 this.phoneNumber = number; 3 this.phoneNumber1 = number; 4 this.phoneNumber2 = number; 5 this.phoneNumber3 = number; 6 this.phoneNumber4 = number; 7 this.phoneNumber5 = number; 8} 9function SmartPhone(number, wifispots) { 10 this.wifispots = wifispots; 11 this.phoneNumber = number; 12 this.phoneNumber1 = number; 13 this.phoneNumber2 = number; 14 this.phoneNumber3 = number; 15 this.phoneNumber4 = number; 16 this.phoneNumber5 = number; 17} 18martPhone.prototype = new CellPhone();

↑こんな感じに書くと、さすがにバカっぽいので再利用したほうがいいからです。

ところでこの時に、

javascript

1function CellPhone(number) { 2 this.phoneNumber = number; 3} 4function SmartPhone(number, wifispots) { 5 this.wifispots = wifispots; 6 CellPhone(number); 7} 8martPhone.prototype = new CellPhone();

こう書いてしまうと上手くいきません。

なぜなら、

javascript

1function CellPhone(number) { 2 this.phoneNumber = number; // ここのthisと 3} 4function SmartPhone(number, wifispots) { 5 this.wifispots = wifispots; // ここのthisの中身が違う。 6 CellPhone(number); 7} 8martPhone.prototype = new CellPhone();

thisは文脈によって中身が変わるからです。こっちでのthisをあっちに渡さないといけません。
callメソッドの書式はfun.call(thisArg[, arg1[, arg2[, ...]]])となっており、あっちでのthisを指定することができます。



ちなみに、bindメソッドでも同じことができます。

javascript

1 CellPhone.bind(this)(number);

 


javascriptのプロトタイプ継承は無駄に複雑ですので、すべてを忘れてclass構文+Babelを使った方が幸せになれるかもしれません。

投稿2017/10/10 03:13

Lhankor_Mhy

総合スコア36074

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

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

takane

2017/10/10 04:28

長くなるコードを省略する目的で使われているのですね。 個人的にはあまり使うことがなさそうですが callは決行たくさん見かけます。 ありがとうございます。
Lhankor_Mhy

2017/10/10 06:13

> 長くなるコードを省略する目的で使われている あくまでこのコードではそう、というだけです。 Array.prototype.slice.call のように、オブジェクトにあるメソッドを別のオブジェクトを対象にして使いたい時に使うことが多いです。
guest

0

まずはドキュメントを読まれましたでしょうか?ここにはcallがどういう働きをするか書かれています。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/call

もしここを読んだ上でよくわからないというのであれば、質問に「リファレンスを読んだが理解が及ばない」と一言付けてもらえば、できるだけ優しく解説されると思います。

投稿2017/10/10 02:16

masaya_ohashi

総合スコア9206

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

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

takane

2017/10/10 04:29

うーん、私の頭がわるいのかもしれません、 読んでも読んでもはてなという感じでした。 気をつけます。
masaya_ohashi

2017/10/10 04:33

初級者で理解が出来ないのはべつに悪いことではありません。私も意地悪で言ったのではなく、まずは一番詳しく書いてあるリファレンスを読んで、それでもわからないなら解説を求めるというのが正しい勉強の手順だと思うからです。なんとなく入門サイトのコードを眺めるだけでなく、本家の説明も読めるようになるのがレベルアップの第一歩です。がんばってください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問