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

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

ただいまの
回答率

88.23%

javascriptにおけるthisの参照

解決済

回答 3

投稿

  • 評価
  • クリップ 2
  • VIEW 2,018

MasakazuFukami

score 1832

初歩的な質問で申し訳ございません。
javascriptにおけるthisの振る舞いがわかりません。

【やりたいこと】
下のコードでresizeTouphone.ratio.wを正常に出力したい

現在のコードでresizeToiphone.ratio.wを出力するとundefinedになってしまいます。

var resizeToiphone = {
  wWidth  : document.documentElement.clientWidth,
  wHeight : document.documentElement.clientHeight,
  iWidth  : 320,
  iHeight : 568,
  ratio   : {
    w : this.iWidth/this.wWidth,
    h : this.iHeight/this.wHeight
  }
}
こちら何が原因なのでしょうか。
よろしくお願いいたします。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+3

まず何が原因かということなのですがJavaScriptのthisは可変です。Objectや無名関数の中でthis
はwindow(グローバルスコープ)を指します。
var a={
  b : {
    c: this
  }
}
console.log(a.b.c);//window
どうしてもthisを使用したいということであれば以下のようにコンストラクタを使用することで実現できます
まず無名のコンストラクタを使用した場合です。普段thisの乱用はお勧めしませんが……
resizeToiphone=(new function (){
  this.wWidth=document.documentElement.clientWidth;
  this.wHeight=document.documentElement.clientHeight;
  this.iWidth=320;
  this.iHeight=568;
  this.ratio={
      w : this.iWidth/this.wWidth,
      h : this.iHeight/this.wHeight
  }
  return;
}());

console.log(resizeToiphone.ratio.w);//0.23721275018532245
こちらのコードは上のコードとは違う視点から。
即時関数の中でコンストラクタを作成し、return newでコンストラクタをObject化して変数resizeToiphoneへ代入。
resizeToiphone=(function () {
  function resizeToiphone(){
    resizeToiphone.prototype.wWidth = document.documentElement.clientWidth;
    resizeToiphone.prototype.wHeight = document.documentElement.clientHeight;
    resizeToiphone.prototype.iWidth = 320;
    resizeToiphone.prototype.iHeight = 568;
    resizeToiphone.prototype.ratio = {
      w: this.iWidth / this.wWidth,
      h: this.iHeight / this.wHeight
    }
  };
  return new resizeToiphone();
}());

console.log(resizeToiphone.ratio.w); //0.23721275018532245

気持ちの悪いコードですが以下もコンストラクタを使用した例です。
こちらはお勧めしません。(可読性などのほかにも色々問題がありますが何より気持ち悪いという)
resizeToiphone=(new function resizeToiphone(){
  resizeToiphone.prototype.wWidth=document.documentElement.clientWidth;
  resizeToiphone.prototype.wHeight=document.documentElement.clientHeight;
  resizeToiphone.prototype.iWidth=320;
  resizeToiphone.prototype.iHeight=568;
  resizeToiphone.prototype.ratio={
      w : this.iWidth/this.wWidth,
      h : this.iHeight/this.wHeight
  }
}());
console.log(resizeToiphone.ratio.w);//0.23721275018532245

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

-1

メソッド内でthisは利用出来るはずです。
this利用しなくても行けそうなので
var resizeToiphone = {
  wWidth  : document.documentElement.clientWidth,
  wHeight : document.documentElement.clientHeight,
  iWidth  : 320,
  iHeight : 568,
  ratio   : {}
}

resizeToiphone.ratio = {
    w : resizeToiphone.iWidth/resizeToiphone.wWidth,
    h : resizeToiphone.iHeight/resizeToiphone.wHeight
};
console.log(resizeToiphone.ratio.w);
このような感じで書くか、
thisを利用して書くのであれば
var resizeToiphone = {
  wWidth  : document.documentElement.clientWidth,
  wHeight : document.documentElement.clientHeight,
  iWidth  : 320,
  iHeight : 568,
  ratio   : function () {
    return {
      w : this.iWidth/this.wWidth,
      h : this.iHeight/this.wHeight
    };
  }
};
console.log(resizeToiphone.ratio().w);
このような感じでも動くと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/07 21:15

    回答有難うございます!!
    メソッド内だとthisが使用できるんですね!!!
    参考にさせていただきます!!!!!

    キャンセル

-1

thisというのはその空間内(メソッドやオブジェクト内)の変数を指します
ratio内にiwidthは存在しないので未定義になるわけです
こういう場合の常用手段としてthatを使います

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/16 15:28

    ratioを指している訳ではありませんよ。もう一度thisの動作について調べてみることをお勧めします。

    ```lang-javascript
    function OutputManage(){
    var that=this;
    OutputManage.prototype.console=function (_string){
    console.log(_string);
    return this;
    }
    OutputManage.prototype.alert=function (_string){
    alert(_string);
    return this;
    }
    OutputManage.prototype.setConsoleLog=function (_element,_string){
    _element.addEventListener("click",function (){
    //ここからthis(OutputManage)を参照できない
    //この場合function(){/**/}.bind(this)か変数thatまたはselfにthisを代入して使う
    that.console(_string);
    },false);
    return this;
    }
    }

    var output=new OutputManage();
    output.setConsoleLog(document.body,"test");
    ```

    キャンセル

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

  • ただいまの回答率 88.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る