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

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

ただいまの
回答率

87.59%

[javascript]静的プロパティとローカル変数の違い

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,606

わからないこと

コンストラクタ単位で保有される静的プロパティとコンストラクタの中で定義されるローカル変数の違いが分かりません。
同じ読み取り専用という点ではほぼ同じように思えます。
静的プロパティとローカル変数の両者で、機能的にここが違うという明確な部分を教えていただきたいです。

コード

let Test = function(test_name){
  //ローカル変数
  let version = "1.0";
  let showVersion = function(){
    return `version${version}`;
  }
  //インスタンス変数
  this.test_name = test_name;
  this.name_and_version = function(){
    return `name is ${this.test_name} | ${showVersion()}`;
  }
}
let test1 = new Test("test1");
console.log(test1.name_and_version());
/*
出力: name is test1 | version1.0
*/

/*
クラス変数
*/
Test.version = "2.0";
Test.showVersion = function(){
  return `version${Test.version}`;
}
console.log(Test.version);
console.log(Test.showVersion());
/*
出力: 2.0
     version2.0
*/

追記

Testクラス内のversion(ローカル変数?)には、Testクラスのインスタンスtest1からアクセスできません。
Testクラスに追加した静的プロパティ(version2.0)にも、Testクラスのインスタンスtest1からアクセスできません。
同じようにアクセスできない(書き換えられない)ローカル変数と静的プロパティの違いが知りたいです。

何卒、ご回答のほどよろしくお願いいたします。

ここが知りたい

・どちらもインスタンス自体から呼び出すことはできない
・どちらもインスタンスメソッド経由だと(コンストラクタ内だと)アクセスすることができる

この点を踏まえて、この両者は

①明確にどこが違うのか
②どう使い分けたら良いのか

が知りたいです。

let Test = function(text){
  //ローカル変数
  let local_value = "local value";
  let local_function = function(){
    return "local_function: " + local_value;
  }
  //インスタンス変数
  this.text = text;
  this.showText = function(){
    return "showText: " + this.text;
  }
  //インスタンス変数-ローカル変数local_functionを呼び出す
  this.use_local_function = function(){
    return local_function();
  }
  //インスタンス変数-静的プロパティstatic_functionを呼び出す
  this.use_static_function = function(){
    return Test.static_function();
  }
}
//静的プロパティ
Test.static_value = "static value";
Test.static_function = function(){
  return "static_function: " + Test.static_value;
}

let test_obj = new Test("test-text");
console.log(test_obj.showText()); //・・・インスタンスメソッドなので当然呼び出せる
//console.log(test_obj.local_function()); ・・・ローカル変数なのでインスタンス経由で呼び出せない
//console.log(test_obj.static_function()); ・・・静的プロパティなのでインスタンス経由で呼び出せない
console.log(test_obj.use_local_function()); //・・・インスタンスメソッドを通してだとローカル変数にアクセスできる
console.log(test_obj.use_static_function()); //・・・インスタンスメソッドを通してだと静的プロパティにアクセスできる
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • pikapika-itinen

    2019/08/10 16:46

    もう少し考えてみます・・・。

    キャンセル

  • m.ts10806

    2019/08/10 16:50

    あいえ、そういうことではなくて、「質問内容に対して重要なことがこちらのコメント欄で書かれていて埋もれてしまうので質問本文に追記してください」ということです。

    キャンセル

  • pikapika-itinen

    2019/08/10 16:52

    理解力が乏しく、申し訳ございません。
    追記しておきます。

    キャンセル

回答 3

checkベストアンサー

+1

同じ読み取り専用という点ではほぼ同じように思えます。

えっと、プロパティは書き換え可能ですが。

let Test = function(test_name){
  //ローカル変数
  let version = "1.0";
  let showVersion = function(){
    return `version${version}`;
  }
  //インスタンス変数
  this.test_name = test_name;
  this.name_and_version = function(){
    return `name is ${this.test_name} | ${showVersion()}`;
  }
}
let test1 = new Test("test1");
test1.test_name = "書き換え";
console.log(test1.name_and_version());

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/08/10 17:57

    お答えいただき、ありがとうございます。
    コンストラクタ内から静的メンバにアクセスすることができました。
    ただ、そうなると「インスタンスを経由して呼び出せない値」は、コンストラクタ内に記述したローカル変数(上記コードのversion=1.0とshowVersion)も同じではないのでしょうか。そこの違いといいますか、どう使い分けるのかが分からないのです。

    キャンセル

  • 2019/08/11 07:38

    えっと、コンストラクタ内のローカル変数はコンストラクタの終了後アクセスする方法がないのに対して、クラスプロパティは誰でも書き換え可能と、まったく動作が違う箇所があるのですが、それは無視されている感じでしょうか。

    キャンセル

  • 2019/08/11 12:53

    長くお付き合いいただき、ありがとうございます。
    頭が混乱しておりました・・・。

    キャンセル

+1

・どちらもインスタンス自体から呼び出すことはできない
・どちらもインスタンスメソッド経由だと(コンストラクタ内だと)アクセスすることができる

文言が不正確なので、もし、この文言が書籍で書かれた文章を正確に書き写したもので、解読ミスをしたのであれば、その書籍は混乱を生むだけなので捨てるべきだと思います。

  • #1 どちらもインスタンスオブジェクト(コンストラクタ内での this 値)のプロパティとして呼び出すことはできない
  • #2 どちらもコンストラクタ内/コンストラクタを参照可能なインスタンスメソッド内では、アクセスすることができる(prototype系インスタンスメソッド内からコンストラクタ内のローカル変数参照は出来ない)
'use strict';
function Test () {
  let local_value = "local value";  // ローカル変数

  this.foo = function foo () {
    console.log(local_value);       // "local value" (#2 参照できる)
    console.log(Test.static_value); // "static value" (#2 参照できる)
    console.log(this.local_value);  // undefined (#1 参照できない、this 値はローカル変数を格納するオブジェクトではない)
    console.log(this.static_value); // undefined (#1 参照できない、this 値は静的プロパティを格納するオブジェクトではない)
  };

  console.log(local_value);       // "local value" (#2 参照できる)
  console.log(Test.static_value); // "static value" (#2 参照できる)
  console.log(this.local_value);  // undefined (#1 参照できない、this 値はローカル変数を格納するオブジェクトではない)
  console.log(this.static_value); // undefined (#1 参照できない、this 値は静的プロパティを格納するオブジェクトではない)
}
Test.prototype.bar = function bar () {
  console.log(Test.static_value); // "static value" (#2 参照できる)
  console.log(this.local_value);  // undefined (#1 参照できない、this 値はローカル変数を格納するオブジェクトではない)
  console.log(this.static_value); // undefined (#1 参照できない、this 値は静的プロパティを格納するオブジェクトではない)
  local_value;                    // ReferenceError: local_value is not defined (参照できない、変数のスコープ外)
};

Test.static_value = "static value"; // 静的プロパティ

new Test;
console.log(Test.static_value); // "static value" (参照できる)
local_value;                    // ReferenceError: local_value is not defined (参照できない、変数のスコープ外)

必要な知識は「変数のスコープ」と「コンストラクタ内における this 値の扱い」です。

Re: pikapika-itinen さん

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/08/11 13:12

    確かに不明確でしたね・・・。これは自分の解読ミスです。

    #1 どちらもインスタンスオブジェクト(コンストラクタ内での this 値)のプロパティとして呼び出すことはできない
    #2 どちらもコンストラクタ内/コンストラクタを参照可能なインスタンスメソッド内では、アクセスすることができる(prototype系インスタンスメソッド内からコンストラクタ内のローカル変数参照は出来ない)

    この表現、とてもわかりやすかったです。
    また、サイトもご提示いただきありがとうございます。
    もっと勉強します。

    キャンセル

0

ただ、そうなると「インスタンスを経由して呼び出せない値」は、コンストラクタ内に記述したローカル変数(上記コードのversion=1.0とshowVersion)も同じではないのでしょうか。そこの違いといいますか、どう使い分けるのかが分からないのです。

コンストラクタ内に記述したshowVersionは「静的プロパティ」ではなく「ローカル変数」です(上から4行目)。

クラス変数の下のTest.showVersionが「静的プロパティ」です。

同じ名前だから混同されたのでしょう。

静的プロパティという単語を見たことがありませんでしたが、静的プロパティで検索して理解できました。
https://ja.javascript.info/static-properties-methods

どちらにせよ「同じ読み取り専用」という記述は間違っています。上書きできますので。

let Test = function(test_name){
  //コンストラクタ内に記述したローカル変数
  let version = "1.0";
  let showVersion = function(){
    return `version${version}`;
  };

  version = "2.0"; /* コンストラクタ内に記述したローカル変数versionを上書き */
  showVersion = function(){ /* コンストラクタ内に記述したローカル変数showVersionを上書き */
    return `VERSION${version}`;
  };

  console.log(showVersion()); /* VERSION2.0を出力 */

}
let test1 = new Test("test1");

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/08/10 19:56

    ご回答いただき、ありがとうございます。
    読み取り専用という点、認識を誤っておりました。

    「ここが知りたい」という部分を上に追記しましたので、見ていただけると幸いです。
    お手数おかけしますが、よろしくお願いいたします。

    キャンセル

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

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

関連した質問

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