【问题标题】:How to change the context of a function in javascript如何在javascript中更改函数的上下文
【发布时间】:2010-12-04 21:40:44
【问题描述】:

我试图了解为什么在 javascript 中,您可能想要更改函数的上下文。我正在寻找一个真实世界的例子或一些可以帮助我理解如何/为什么使用这种技术以及它的意义的东西。

使用此示例说明该技术(来自http://ejohn.org/apps/learn/#25

var object = {}; 
function fn(){ 
  return this; 
} 
assert( fn() == this, "The context is the global object." ); 
assert( fn.call(object) == object, "The context is changed to a specific object." );

【问题讨论】:

  • 有趣;我找到了这个页面,因为我需要为正在拨打的电话设置上下文并且不记得语法... :)
  • +1 的标题应为:“如何在 javascript 中更改函数的上下文”(jk - 感谢您发布此内容!)
  • +1 我一直在寻找如何在课堂上保持 this 的一致性...

标签: javascript function scope


【解决方案1】:

jQuery利用它效果很好:

$('a').each(function() {
    // "this" is an a element - very useful
});

实际的 jQuery 代码如下所示:

for ( name in object ) {
    if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
        break;
    }
}

如果它只是做了callback( name, object[ name ] ),那么this 不会被设置为迭代器中的当前对象,您必须改用该参数。基本上它只是让事情变得更容易。

【讨论】:

【解决方案2】:

请看一下这个例子:

<script>
var el = document.getElementById('button');
el.onclick = function(){
    this.value = "Press Me Again"; //this --> now refers to the the element button not on the window
}

//Another Example:
var Person = function(name,location){
  this.name = name;
  this.location = location;  
  alert(this.location); 
}   
var p2 = new Person("Samantha","California"); //this refers to the instance of the function Person(Person now acts as a class)
var p1 = Person(); // this refers to the window(Person simply acts as a simple function)
</script>
<button id="button1">Press Me</button>

新的关键字改变了上下文。

【讨论】:

    【解决方案3】:

    在从 AJAX 请求中进行回调时非常有用:

    function Person(_id, _name) {
        this.id = _id;
        this.name = _name;
    };
    
    Person.prototype.sayHi = function(greeting) {
        alert(greeting + " from " + this.name);
    };
    
    Person.prototype.loadFromAJAX = function(callback) {
        // in this example, it's jQuery, but could be anything
        var t = this;
        $.get("myurl.php", function(data) {
            callback.call(t, data.greeting);
        });
    };
    

    实际上,这是一个非常糟糕的例子。

    在 jQuery 中有大量的使用它。例如 jQuery().get() 函数:

    get: function( num ) {
        return num === undefined ?
            // Return a 'clean' array
            Array.prototype.slice.call( this ) :
            // Return just the object
            this[ num ];
    }
    

    它使用 Array 原型的函数,但在 jQuery 对象的上下文中。

    【讨论】:

      【解决方案4】:

      我遇到的一个真实世界的例子:

      如果您将函数作为事件处理程序添加到 DOM 元素,并且在该函数中使用“this”,则“this”将引用您添加事件处理程序的 DOM 元素。

      但是该函数可能是一个对象的方法,并且您希望其中使用的“this”关键字引用所有者对象...所以您需要更改上下文以便“this" 不会引用 DOM 元素,而是引用 所有者对象

      您可以使用 proxy() 函数轻松更改 jquery 中函数的上下文。 看到这个问题: jquery "this" binding issue on event handler (equivalent of bindAsEventListener in prototype) 和第一个答案

      【讨论】:

        【解决方案5】:

        bind 函数可能是您正在寻找的,bind 函数在您传入的上下文中返回一个新函数,真实世界的场景可能是当您使用 jquery 委托将某些行为附加到 dom 元素时,并且您希望回调在不同的上下文中执行。因为 jquery delgate 中的默认上下文是绑定到处理程序的 dom 对象,这意味着除了属于 dom 对象的属性之外,您无法访问任何属性

        【讨论】:

          【解决方案6】:

          在使用 setTimeout 时,我总是发现自己需要不同的上下文,而 jQuery 有一个方便的函数 $.proxy 可以解决问题:

          function iAmCalledAfterTimeout()
          {
               alert(this.myProperty); //it will alert "hello world"
          }    
          
          setTimeout($.proxy(iAmCalledAfterTimeout, {myProperty:"hello world"}), 1000);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-05-03
            • 2016-12-02
            • 1970-01-01
            • 2022-07-12
            相关资源
            最近更新 更多