請問這里的this指什么?

我已經理解了next("左運動參數")(馬車開始向左運動).then("轉向參數")(馬車轉向).then("右運動參數")(馬車開始向右運動).then()(馬車停止)這種方式。
請問這里的1,2,3號this分別指的是什么?
這里的邏輯怎么樣的?如果讓我寫,我怎么知道這樣去寫,因為這里很不符合初學者思維習慣。

這里的callback干什么用?

這里的this為什么要存到that去?
如果不用that保存this,那么this的引用會在哪被更改?

我已經理解了next("左運動參數")(馬車開始向左運動).then("轉向參數")(馬車轉向).then("右運動參數")(馬車開始向右運動).then()(馬車停止)這種方式。
請問這里的1,2,3號this分別指的是什么?
這里的邏輯怎么樣的?如果讓我寫,我怎么知道這樣去寫,因為這里很不符合初學者思維習慣。

這里的callback干什么用?

這里的this為什么要存到that去?
如果不用that保存this,那么this的引用會在哪被更改?
2017-09-12
舉報
2017-12-27
2樓說的不錯.
我補充幾點
先說下apply()函數
var?add?=?function(a,b){ ????return?a?+?b; } var?sub?=?function(a,b){ ????return?a?-?b; } var?result?=?add.apply(sub,[8,1]); var?result_1?=?sub.apply(add,[8,1]); console.log(result);?//?9 console.log(result_1);?//?7 apply()是函數對象的一個方法, 它的作用是改變函數的調用對象, 它的第一個參數就表示改變后的調用這個函數的對象。關于 this 關鍵字 參考此鏈接
http://www.ruanyifeng.com/blog/2010/04/using_this_keyword_in_javascript.html
我們分析一下var next = function(){...}這個函數
var?next?=?function(){ ???return?this.next.apply(this,arguments); }.bind(this)?第一個和第二個this都在next()函數的內部
而第三個this就不在next()的內部,而是屬于pageA.prototype.run = function(callback){...}這個函數內部了.
而next()函數是全局對象global或window的方法,所以在next()函數內部的this就是指向他們了
而pageA.prototype.run = function(callback){...}這個函數內部的this是如下傳遞過來的
function?pageA?(element)?{ ????//?this?指向pageA的實例對象 ????//根元素 ????this.$root?=?element; ????//小男孩 ????this.$boy?=?element.find(".chs-boy"); ????//?執行pageA的實例對象的run方法 ????this.run(); }如果我們給這個實例對象命個名
那么第三個this就是由
this.run(); 傳遞過來的something對象了
我們再看bind()函數
function?add(a,b){???? ????return?a?+?b; } var?a?=?3; var?b?=?4; var?newFoo?=?add.bind(this,a,?b);? a?=?6; b?=?7; console.log(newFoo());??//?7 console.log(this.a);??//?6 console.log(this.b);?//?7由此,我們可以得出結論
bind()函數 綁定的是參數的值,而不是實際變量的值。
再看這個例子
this.num?=?9;? var?module?=?{?? num:?81,? getNum:?function()?{?return?this.num;} } ? module.getNum();?//?81 var?getNum?=?module.getNum; getNum();?//?9,?因為在這個例子中,"this"指向全局對象 //?創建一個'this'綁定到module的函數 var?boundGetNum?=?getNum.bind(module); boundGetNum();??//?81由此,我們可以得出結論
bind()函數 改變了this的指向
綜上
我們完全可以這樣寫
//?給pageA添加run方法 pageA.prototype.run?=?function(){ ????//?存儲當前上下文對象:?pageA的實例對象 ????var?that?=?this; ???? ????//?定義next方法?注意:此處不是pageA的next方法 ????//?而是是pageA的run方法里面的next方法. ????var?next?=?function(){ ????????return?this.next.apply(this,arguments) ????????//?注意?這里不寫this?寫的是that?意圖更明顯 ????}.bind(that) ???? ????//?這里調用的就是上面聲明的next方法 ????//?注意?上面用var聲明的next()是沒有定義參數的 ????//?但是用了?arguments?這個關鍵字取得了傳入的參數 ????next({ ????????"time":?10000, ????????"style":?{ ????????????"top":?"4rem", ????????????"right":?"16rem", ????????????"scale":?"1.2" ????????} ????}) ????.then(function()?{ ???????return?next({ ????????????"time":500, ????????????"style":?{ ???????????????"rotateY"?:?"-180", ???????????????"scale":?"1.5" ????????????} ????????}) ????})???? ????.then(function()?{ ????????return?next({ ????????????"time":?7000, ????????????"style":?{ ????????????????"top"???:"7.8rem", ????????????????"right"?:?"1.2rem" ????????????} ????????}) ????}) ????.then(function(){ ????????that.stopWalk(); ????})?? }就目前的情況也可以這樣寫
?//?給pageA添加run方法 pageA.prototype.run?=?function(){ ????this.next({ ????????"time":?10000, ????????"style":?{ ????????????"top":?"4rem", ????????????"right":?"16rem", ????????????"scale":?"1.2" ????????} ????}) ????.then(function()?{ ???????return?this.next({ ????????????"time":500, ????????????"style":?{ ???????????????"rotateY"?:?"-180", ???????????????"scale":?"1.5" ????????????} ????????}) ????})???? ????.then(function()?{ ????????return?this.next({ ????????????"time":?7000, ????????????"style":?{ ????????????????"top"???:"7.8rem", ????????????????"right"?:?"1.2rem" ????????????} ????????}) ????}) ????.then(function(){ ????//?注意:?此處不再是that ????????this.stopWalk(); ????})?? }2017-12-27
再補充一下....
突然發現有一點沒說
就是為什么要多此一舉聲明另一個next()函數,然后用apply()和bind()函數來將對象轉移呢?
我猜測啊,應該是避免異步導致的參數賦值混亂.我猜的哈
總之這樣寫應該是有其作用的
因為我聽說過一句話:任何編程方面的問題,都可以通過添加一個中間件的方式得到解決.
2017-12-27
再補充一下 callback 是回調函數 目前沒用? 刪掉也沒關系
下節應該會用到
2017-09-28
第三個this指向的是構造函數pageA new出的對象,也就是對象本身。
第一個和第二個this本應指向window,但被bind改變了指向,所以也指向對象本身。