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

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

場(chǎng)景:

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

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

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

我開(kāi)始是這么做的:

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

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

可能是我的思路不對(duì), 像這種需要抽取方法的場(chǎng)景應(yīng)該怎么做呢?
完全沒(méi)有java真正面向?qū)ο蟮膩?lái)的方便和易于理解呀!!!

回答
編輯回答
扯機(jī)薄

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

我試了一下以下代碼(手機(jī)上只有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 {}

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

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

關(guān)鍵原因是因?yàn)槲以?code>Graph.prototype.fun()中使用了數(shù)組.foreach()的代碼
這樣造成:
Graph.prototype.foo 中調(diào)用 subfoo.call(this)(沒(méi)有問(wèn)題,this指向符合預(yù)期), 但是subfoo()中調(diào)用Graph.prototype.fun()后, 在fun()因?yàn)閳?zhí)行了數(shù)組.foreach(), 這樣調(diào)用者不再是graph實(shí)例了, 那么在循環(huán)體里面, this自然就變成了全局window.
所以關(guān)鍵原因是調(diào)用者發(fā)生了變化.
將循環(huán)方式改成計(jì)數(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 { //若邊沒(méi)有type屬性, 則不受類(lèi)型開(kāi)關(guān)限制, 始終顯示
        this.addEdge(edge);
    }
}
2017年7月8日 21:13
編輯回答
安淺陌

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

2017年12月11日 20:58