2 回答

TA貢獻(xiàn)1877條經(jīng)驗(yàn) 獲得超6個(gè)贊
面向?qū)ο笳Z言來說,舉Java的例子:
class Foo { boolean bar() { return this.getClass() == Foo.class; } class InnerFoo { boolean baz() { return this.getClass() == InnerFoo.class; } boolean baz2() { return Foo.this.getClass() == Foo.class; } } }
bar里面的this指向的是Foo類型的對(duì)象,baz里面的this指向的是InnerFoo類型的對(duì)象,而baz2里面的Foo.this指向的是外層的Foo類型的對(duì)象,所以需要用Foo來限定。
其實(shí)把對(duì)象本身作為參數(shù)顯式的傳入并不是什么bad practise,在Python中就是這樣約定的:
class MyClass: def __init__(self, name): self.name = name def greet(self, friend): print self.name, "says hello to", friend
所以在JS中,需要特殊的處理this綁定的問題,比如用var that = this然后引用that就是一個(gè)常用的方法。
函數(shù)編程里雖然沒有this變量作為隱含參數(shù)傳入,但是事實(shí)上是有更有效的工具的:閉包(closure)。事實(shí)上this變量可以算是閉包的一種情況。而在一些dynamic scoping的語言(如elisp)里面,函數(shù)的運(yùn)行依賴于調(diào)用環(huán)境,所以“隱含的參數(shù)”其實(shí)更多。
我個(gè)人的看法是,面向?qū)ο罄锩鏋榱朔奖悖ɑ蛘邚?qiáng)調(diào))封裝(encapsulation),把數(shù)據(jù)和操作綁定在一起,“this”的地位才如此重要。而函數(shù)編程語言中,第一公民是函數(shù)(操作)而不是數(shù)據(jù),所以并沒有this的地位。這兩者是不同的思維范式,取長補(bǔ)短即可。

TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超4個(gè)贊
從forEach
這個(gè)具體的例子來看,問題倒比較容易解決,畢竟
Array.forEach(callback[, thisArg])
里可以直接將外層的this
傳入,這樣就解決了。
從更一般的角度來看,以我愚見,定義一個(gè)var this_
,雖然不太好看,但是在需要多次使用外層的this
的時(shí)候,還是很方便的。
如果不需要多次使用this
的話,Function.bind
也可以在一定程度上解決這個(gè)問題。
想要根本上解決這個(gè)問題,也可以考慮在每個(gè)構(gòu)造函數(shù)里加入類似這樣的代碼:
// methodNames是一個(gè)包含所有方法名稱的ArraymethodNames.forEach(function(name) { this[name] = this[name].bind(this) }, this);
缺點(diǎn)是這么做會(huì)大大降低運(yùn)行效率,而且也不好看。
總的來說這是Javascript
的設(shè)計(jì)上的問題,只能繞過去了。
如果是用CoffeeScript的話,那么可以使用它提供的=>
來定義一個(gè)保留外層this
的函數(shù):
class Tree constructor: (@value, @children) -> show: () -> @children.forEach (child) => # Note the fat arrow (=>) used here console.log "<Tree %s %s>", @value, child t = new Tree "root", [1, 2, 3] t.show()
這個(gè)功能看起來還是不錯(cuò)的..
添加回答
舉報(bào)