javascript中方法抽取和调用问题

发布于 2022-09-06 21:40:40 字数 980 浏览 13 评论 0

场景:

现有一个对象, 通过prototype关键字添加了方法foo():

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

现在foo()方法中的逻辑太复杂, 所以想要将某一功能代码抽取成一个新的方法subfoo().
这个时候, 我应该怎么做呢?

我开始是这么做的:

var Graph = new Graph();
Graph.prototype.foo = function(){
    ....
    function subfoo(){
        //调用了fun()方法
        this.fun();    //能够成功调用graph的fun(), 但是走到fun()体中时, this就变成了window, 预期的是想要依然指向graph
    }
    //调用subfoo()方法
    subfoo.call(this);    //让this指向graph实例, 传入subfoo()
}

但是, 当我在subfoo()中又调用了一个Graph.prototype.fun方法时, 走到fun()时, 其中的this指针就会变成了window, 即使使用call也无效. 想要的当然是一直指向graph.

可能是我的思路不对, 像这种需要抽取方法的场景应该怎么做呢?
完全没有java真正面向对象的来的方便和易于理解呀!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

|煩躁 2022-09-13 21:40:40

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

尴尬癌患者 2022-09-13 21:40:40

func()?哪来的func()?能不能把你的代码补充完整,包括你在哪里用了this,并且把你期望这个this指向哪个对象也补上。我猜你可能用了箭头函数,箭头函数没有this关键字哦。

我试了一下以下代码(手机上只有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();

结果是

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

非常的正常,不知道你有没有漏了什么信息没有提供的,当然也有可能是浏览器和node的差别。另外你在什么浏览器上测试的?我中午或下午可以在浏览器上测试一下。

怀中猫帐中妖 2022-09-13 21:40:40

关键原因是因为我在Graph.prototype.fun()中使用了数组.foreach()的代码
这样造成:
Graph.prototype.foo 中调用 subfoo.call(this)(没有问题,this指向符合预期), 但是subfoo()中调用Graph.prototype.fun()后, 在fun()因为执行了数组.foreach(), 这样调用者不再是graph实例了, 那么在循环体里面, this自然就变成了全局window.
所以关键原因是调用者发生了变化.
将循环方式改成计数循环, 则又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属性, 则不受类型开关限制, 始终显示
        this.addEdge(edge);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文