如何在javascript中更改函数的上下文

时间:2009-10-08 07:29:20

标签: javascript function scope

我试图理解为什么在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." );

6 个答案:

答案 0 :(得分:20)

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将不会被设置为迭代器中的当前对象,而您必须使用该参数。基本上它只是让事情变得更容易。

答案 1 :(得分:6)

请看一下这个例子:

<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>

新关键字会更改背景。

答案 2 :(得分: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对象的上下文中。

答案 3 :(得分:3)

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

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

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:0)

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

function iAmCalledAfterTimeout()
{
     alert(this.myProperty); //it will alert "hello world"
}    

setTimeout($.proxy(iAmCalledAfterTimeout, {myProperty:"hello world"}), 1000);