LoginSignup
2
3

More than 5 years have passed since last update.

JavaScriptのスコープについて

Last updated at Posted at 2016-08-23

はじめに

はじめまして
去年まで専門学校に通っていたゆとりの新社会人、ポンコツエンジニアです。
まだまだ、駆け出しなので間違った事を書いている可能性があるので
何かお気付きの点などがございましたら、ご指導のほどよろしくお願いします。

投稿の背景

 さて、今回こういった投稿をする事になった経緯としては
最近、JavaScriptを学習しなくてはならない環境になり
いろいろと理解していないことを痛感したので、これを良い機会に学習していこう
と思ったことが事の始まりです。

 今後も投稿する事があると思いますが、
「備忘録」といったスタンスで学習した内容を記録に残そうという意図を持って
書いているので、参考にしたい方はちゃんと理解している人のサイトを見つけてね(笑)

では、本題に入って行きたいと思います

JavaScriptにおけるスコープについて

そもそも、スコープとはなんぞやってことで調べてきました。

スコープ(scope)とは

スコープとは、変数の有効範囲のことで、プログラムのどの場所から参照できるかを決める概念だそう。

スコープの種類

JavaScriptのスコープには、グローバル変数とローカル変数がある。
(まぁJavaScriptに限ったことじゃないけどね。)

       グローバル変数 ローカル変数
 宣言場所  関数の外で宣言した変数  関数の中で宣言した変数、関数の仮引数
 有効範囲  プログラム全体から参照できる  その関数の中でのみ参照できる

宣言場所って文章だけだと
イメージ付きにくいと思うので
コードを書きました(笑)

hoge1.js

var str1 = 'hello';  <--グローバル変数

function printStr(){

    var str2 = 'world'; <- プライベート変数

}

スコープの有効範囲

実際の有効範囲としてはこんな感じかな

hoge2.js
var str1 = 'hello';

console.log(str1); <- helloと表示される

function printStr () {

    var str2 = 'world';

    console.log(str2); <- worldと表示される

    console.log(str1); <- helloと表示される
}

console.log(str2); <- エラーになる

つまり

str1printStr()の外で宣言したのでグローバル変数となり
printStr()の中からも参照は出来るが、
逆にstr2printStr()の中で宣言したのでローカル変数となり
関数の外からは参照出来ないってこと!

JavaScriptにおける this について

JavaScriptにもthisってあるんですね
ただ少しJavaと違います。
今日そのおかげで仕事場でちょっと恥をかきました(笑)
なので、そのへんも記録に残したいと思います

this ってなんやねん

意味は英語でいうと「この~」とかなんですけど
プログラミンではちょっと意味が違ってくるんですよね。。。

2016/8/24訂正
簡単に言えば現在のオブジェクトを指すってことです。
ちょっとわかりにくいですね(笑)

正しい情報を教えて頂きました

JavaScriptの this キーワードは理解しづらいもので、他のオブジェクト指向言語によくある“現在のインスタンス(またはクラス)を参照するもの”ではありません。
通常JavaScriptにおいて、関数内で呼び出された this は、関数呼び出し元のオブジェクトを参照することになります。

inoinojpさん、ありがとうございます。

例としてコードを書いてみました

scope1.js
var str = 'global';// <- `window`オブジェクトに宣言

function getStr(){
    var str = 'obj'
    console.log(this.str); // <- 呼び出されたthis
}

getStr(); //<- 関数呼び出し元

最上層のグローバルオブジェクトは window オブジェクトである

という事なので、
今回の場合、getStr()を呼んでいる場所はwindowオブジェクトになるという事ですね
すなわち、console.log(this.srt);this.strの部分はwindow.strと言い換えてもいいですね

次の例を見てみましょう

scope2.js
var str = 'global'
var Obj = {
    str:'object',
    getStr:function(){
    return console.log(this.str);
    } 
}
Obj.getStr();

この場合、呼び出している場所はwindowオブジェクト配下になるんですが、
Obj.getStr();というコードはObjオブジェクトのgetStr()を呼び出せとなっているので呼び出し元はObjオブジェクトとなるわけです。
よって、出力されるのはobjectとなります。

this のメリットについて調べた結果

  1. 汎用的なfunctionが書ける
hege3.js

function human(age){
   this.age = age;
}

human.prototype.print = function () {    
    console.log(this.age+"");

}
var boy = new human("23");
boy.print();

var girl = new human("20");
girl.print();

このコードを実行すると表示されるのはboy.printでは23歳girl.print()では20歳なんです。
これで汎用的な書き方ができそうですね!

次回はコメントで頂いた

new 演算子を用いて生成されたインスタンスオブジェクトの場合、 this は自身のオブジェクトを参照します。
その他にも Function.prototype.call() などといった this キーワードの参照先を変更させるメソッドも用意されており、これもまたクセのある仕様になっている点(ここでは割愛しますが)に注意が必要です。

と言う部分のnew演算子についての復習とFunction.prototype.call()と言うワードについて学習していこうと思います。

2
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3