繁体   English   中英

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

[英]How to change the context of a function in javascript

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

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

请看一下这个例子:

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

新关键字会更改上下文。

从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对象的上下文中。

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

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

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

您可以使用proxy()函数轻松更改jquery中函数的上下文。 看到这个问题: jquery在事件处理程序上的“this”绑定问题(相当于原型中的bindAsEventListener)和第一个答案

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM