亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

有時候會用一個 _this 來讓 this 穿透函數定義, 但我想不是個好辦法啊,還有其他方法嗎?

有時候會用一個 _this 來讓 this 穿透函數定義, 但我想不是個好辦法啊,還有其他方法嗎?

慕斯王 2023-04-28 23:19:11
一個不明白的問題. 剛開始我學的是用函數式的寫法, 而且在 JS 函數嵌套函數是很容易的, 這么就搞定了.后來我接觸到 JS 的 this, 理解每個函數的 this 指向自身所屬對象, 接著就開始接觸 OOP 的內容了.但這里有個問題, 如果我再對函數進行嵌套, this 就可能出錯了.比如一個對象的方法里, 里邊再定義函數用來作為參數傳遞..或者僅僅是 forEach 增加一層作用域:obj =   people: ['a', 'b', c]   data:    a: 'aaa'     b: 'aaa'     c: 'aaa'   say: ->     this.people.forEach (name) ->       console.log this.data[name]obj.say()在函數式編程里, 沒有看到 this 這樣其葩的功能, 而在有 C/Java 一類語言, 不常用嵌套函數的.就像兩個東西不能很好地兼容似的... 但兩個都被直接拿過來用在了腳本語言里邊不知道有沒有好的方案來解決?
查看完整描述

2 回答

?
慕哥9229398

TA貢獻1877條經驗 獲得超6個贊

面向對象語言來說,舉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類型的對象,baz里面的this指向的是InnerFoo類型的對象,而baz2里面的Foo.this指向的是外層的Foo類型的對象,所以需要用Foo來限定。

其實把對象本身作為參數顯式的傳入并不是什么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就是一個常用的方法。

函數編程里雖然沒有this變量作為隱含參數傳入,但是事實上是有更有效的工具的:閉包(closure)。事實上this變量可以算是閉包的一種情況。而在一些dynamic scoping的語言(如elisp)里面,函數的運行依賴于調用環境,所以“隱含的參數”其實更多。

我個人的看法是,面向對象里面為了方便(或者強調)封裝(encapsulation),把數據和操作綁定在一起,“this”的地位才如此重要。而函數編程語言中,第一公民是函數(操作)而不是數據,所以并沒有this的地位。這兩者是不同的思維范式,取長補短即可。


查看完整回答
反對 回復 2023-05-02
?
蝴蝶不菲

TA貢獻1810條經驗 獲得超4個贊

forEach這個具體的例子來看,問題倒比較容易解決,畢竟

Array.forEach(callback[, thisArg])

里可以直接將外層的this傳入,這樣就解決了。

從更一般的角度來看,以我愚見,定義一個var this_,雖然不太好看,但是在需要多次使用外層的this的時候,還是很方便的。
如果不需要多次使用this的話,Function.bind也可以在一定程度上解決這個問題。

想要根本上解決這個問題,也可以考慮在每個構造函數里加入類似這樣的代碼:

// methodNames是一個包含所有方法名稱的ArraymethodNames.forEach(function(name) {    this[name] = this[name].bind(this)
}, this);

缺點是這么做會大大降低運行效率,而且也不好看。

總的來說這是Javascript的設計上的問題,只能繞過去了。

如果是用CoffeeScript的話,那么可以使用它提供的=>來定義一個保留外層this的函數:

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()

這個功能看起來還是不錯的..


查看完整回答
反對 回復 2023-05-02
  • 2 回答
  • 0 關注
  • 159 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號