this.v と v


JavaScript の this というか、this のつかない名前の意味がなんとなくわかった。JavaScript のスコープ規則では、オブジェクトのフィールドはスコープに含まれないために、this をつけない場合には、外側のスコープの変数を参照する。Java とは異なるけれども、理解してしまえば、これはこれで素直。

> var v = 10;
> var myObject = { v: 0, increment: function (x) { this.v += x; }};
> myObject.increment(5)
> v
10
> myObject.v;
5

に対して、

> var myObject = { v: 0, increment: function (x) { v += x; }}
> myObject.increment(5);
> v;
15
> myObject.v
0

—–

dagelzi さんからのコメントを受けて、ちょっと追加。今、読んでいる JavaScript the Good Parts によれば:

>When a function is invoked with this pattern (注: function invocation pattern), “this” is bound to the global object. This was a mistake in the design of the language. Had the language been designed correctly, when the inner function is invoked, “this” would still be bound to the “this” variable of the outer function.

だそうです。で、この問題を示すのが double1、これを避ける標準的な方法が double2、自分でいいかげんに作ったもうひとつの例が double3。

function add(x, y) { return x + y; }

var myObject = {
value: 3,
increment: function (inc) {
this.value += typeof inc === ‘number’ ? inc : 1;
},
getValue: function () { return this.value; }
};

myObject.double1 = function() {
var helper = function() {
this.value = add(this.value, this.value);
};

helper();
};

myObject.double2 = function() {
var that = this;

var helper = function() {
that.value = add(that.value, that.value);
};

helper();
};

myObject.double3 = function() {
var helper = function(that) {
that.value = add(that.value, that.value);
};

helper(this);
};

print(‘calling double1’);
myObject.double1();
print(myObject.getValue());

print(‘calling double2’);
myObject.double2();
print(myObject.getValue());

print(‘calling double3’);
myObject.double3();
print(myObject.getValue());

this.v と v」への3件のフィードバック

  1. Scheme のようでというより、そもそも Brendan Eich が Netscape に入社したときの目的が、Netscape に Scheme をのせることだったらしいですよ。だから、JavaScript を理解するのに、Scheme と Self から学ぶのが近道なんじゃないかな?Java とか C++ は余計な知識が邪魔しそう。

    ところで dagezi はいつまで Self をいじってたの?

  2. 目標は schemeだったんですか。そういわれると何となく納得です。

    Selfは実はいじってたのは学生の頃だけですよ。といっても、ほんとうに表面だけですが。

コメントは受け付けていません。