鍍金池/ 問答/C++  數(shù)據(jù)庫  HTML/ javascript中方法抽取和調(diào)用問題

javascript中方法抽取和調(diào)用問題

場景:

現(xiàn)有一個對象, 通過prototype關(guān)鍵字添加了方法foo():

var Graph = new Graph();
//foo
Graph.prototype.foo = function(){
    ...
}
//fun
Graph.prototype.fun = function(){
    ...
}

現(xiàn)在foo()方法中的邏輯太復雜, 所以想要將某一功能代碼抽取成一個新的方法subfoo().
這個時候, 我應(yīng)該怎么做呢?

我開始是這么做的:

var Graph = new Graph();
Graph.prototype.foo = function(){
    ....
    function subfoo(){
        //調(diào)用了fun()方法
        this.fun();    //能夠成功調(diào)用graph的fun(), 但是走到fun()體中時, this就變成了window, 預期的是想要依然指向graph
    }
    //調(diào)用subfoo()方法
    subfoo.call(this);    //讓this指向graph實例, 傳入subfoo()
}

但是, 當我在subfoo()中又調(diào)用了一個Graph.prototype.fun方法時, 走到fun()時, 其中的this指針就會變成了window, 即使使用call也無效. 想要的當然是一直指向graph.

可能是我的思路不對, 像這種需要抽取方法的場景應(yīng)該怎么做呢?
完全沒有java真正面向?qū)ο蟮膩淼姆奖愫鸵子诶斫庋?!!

回答
編輯回答
扯機薄

func()?哪來的func()?能不能把你的代碼補充完整,包括你在哪里用了this,并且把你期望這個this指向哪個對象也補上。我猜你可能用了箭頭函數(shù),箭頭函數(shù)沒有this關(guān)鍵字哦。

我試了一下以下代碼(手機上只有node,node的原型是__proto__。瀏覽器上跑不方便)

function Graph() {}

var Graph = new Graph();

Graph.__proto__.foo = function() {
  console.log('old foo', this);
  return this;
}

Graph.__proto__.fun = function() {
  console.log('old fun', this);
  return this;
}

Graph.__proto__.foo = function() {
  console.log('new foo', this);
  function subfoo() {
    console.log('subfoo', this);
    this.fun();
    return this;
  }
  subfoo.call(this);
  return this;
}

Graph.foo();

結(jié)果是

new foo Graph {}
subfoo Graph {}
old fun Graph {}
Graph {}

非常的正常,不知道你有沒有漏了什么信息沒有提供的,當然也有可能是瀏覽器和node的差別。另外你在什么瀏覽器上測試的?我中午或下午可以在瀏覽器上測試一下。

2017年9月26日 06:22
編輯回答
夏夕

關(guān)鍵原因是因為我在Graph.prototype.fun()中使用了數(shù)組.foreach()的代碼
這樣造成:
Graph.prototype.foo 中調(diào)用 subfoo.call(this)(沒有問題,this指向符合預期), 但是subfoo()中調(diào)用Graph.prototype.fun()后, 在fun()因為執(zhí)行了數(shù)組.foreach(), 這樣調(diào)用者不再是graph實例了, 那么在循環(huán)體里面, this自然就變成了全局window.
所以關(guān)鍵原因是調(diào)用者發(fā)生了變化.
將循環(huán)方式改成計數(shù)循環(huán), 則又OK.
修改后的代碼, this指向正確:

for (var i = 0; i < edges.length; i++) {
    var edge = edges[i];
    if (edge.data != null && edge.data.type != null) {
        console.log("this.edgeTypeSet");
        console.log(this.edgeTypeSet);
        if (edge.data.type in this.edgeTypeSet) {
            console.log("this.edgeTypeSet:");
            console.log(this.edgeTypeSet);
            this.addEdge(edge);
        }
    } else { //若邊沒有type屬性, 則不受類型開關(guān)限制, 始終顯示
        this.addEdge(edge);
    }
}
2017年7月8日 21:13
編輯回答
安淺陌

var me=this
function subfoo(){
...
me.foo()
}
試試

2017年12月11日 20:58