为什么这两个javascript函数不等同? [英] Why are these two javascript functions not equivalent?

查看:134
本文介绍了为什么这两个javascript函数不等同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此功能适用于:

function refreshCodeMirror(){
  $("textarea").each(function(){
    var codeMirror = $(this).data('codeMirror');
    setTimeout(function(codeMirror){
      return function () {
        codeMirror.refresh();
      }
    }(codeMirror), 10)

  });
}

但是当我尝试简化为:

function refreshCodeMirror(){
  $("textarea").each(function(){
    var codeMirror = $(this).data('codeMirror');
    setTimeout(codeMirror.refresh, 10)

  });
}

简化不起作用。

某些(可能不相关)的上下文:

Some (possibly irrelevant) context:

refreshCodeMirror函数正在onclick中调用django模板中的引导选项卡标题:

The refreshCodeMirror function is being called in the onclick for a bootstrap tab-header within a django template:

   <div class="row">
        <div class="col-md-12">
            <ul class="nav nav-tabs" role="tablist">
                {% for field in form_tab_fields %}
                    <li role="presentation"{% if forloop.first %} class="active"{% endif %}>
                        <a class="tab-header" href="#{{ field.id_for_label }}_tab" data-toggle="tab" onclick="refreshCodeMirror()">{{ field.label_tag }}</a>
                    </li>
                {% endfor %}
            </ul>
            <div class="tab-content">
                {% for field in form_tab_fields %}
                    <div role="tabpanel"
                         class="form-group tab-pane{% if forloop.first %} active{% endif %}"
                         id="{{ field.id_for_label }}_tab">
                            {{ field }}
                    {{ field.errors }}
                    </div>
                {% endfor %}
            </div>
        </div>
    </div>

上面第一个功能一切正常,而我想删除所有冗余刷新呼叫,它们似乎并不重要,当我使用单个文本区域(通过传递元素id)时,上述工作函数停止工作。

Everything works fine with the first function above and, while I would like to remove all the redundant refresh calls, they don't seem to matter and when I use a single text area (by passing the element id), the working function above stops working.

推荐答案

问题是你失去了上下文。

The problem is you lose the context.

不直接在对象上调用并且不手动绑定到上下文的函数被调用全局上下文

Functions which are not called directly on an object and are not manually bound to a context, are called in the global context.

var obj = {
  print: function() {
    document.write('<pre>' + this + '</pre>');
  }
};

obj.print();
var p = obj.print;
p();

当您使用 setTimeout 或其他类似的功能时,就像这样做:

When you use setTimeout or other similar functions, it's like doing this:

function setTimeout(f, time) {
  wait(time);
  f();
}

所以你的刷新函数期待这个等于你的 codeMirror 实例,而是等于窗口未定义(取决于您是否处于严格模式)。

So your refresh function is expecting this to be equal to your codeMirror instance but instead it's equal to the window or undefined (depending on if you're in strict mode).

是解决这个问题的几种方法。一个是将一个新的函数传递给 setTimeout ,在那里你称之为你的原始函数。

There are a few ways to fix this. One is to pass a new function to setTimeout where you call your original function.

setTimeout(function() {
  codeMirror.refresh();
}, 10);

另一种方式,它使用 bind 将该函数的副本传递给这个设置为正确的对象。

Another way, it to use bind to pass it a copy of the function with this set to the correct object.

setTimeout(codeMirror.refresh.bind(codeMirror), 10);

这篇关于为什么这两个javascript函数不等同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆