当前位置:嗨网首页>书籍在线阅读

10-讨论

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

5.2.3 讨论

$(this) 到底是什么?为什么总是不起作用呢?如果将它分成两部分—— $()this ,就更容易理解。

$() 看上去很神秘,实际上并非如此:它只是一个函数调用。 $ 是对jQuery函数的引用,只是 jQuery() 较为简短的写法而已。它只是返回一个对象的普通JavaScript函数调用。

注意

如果你要使用另一个重新定义 $ 的JavaScript程序库,就是另外一回事了——之后你就不能在jQuery代码中使用 $() ,而应该使用 jQuery() 或者自定义的别名。

this 是jQuery中较容易混淆的特性之一,因为它用在许多不同的方面。在面向对象的JavaScript编程中, this 用于在对象方法中引用该对象,和Python或者Ruby中的 self 类似:

function Foo( value ) {
   this.value = value;
}
Foo.prototype.alert = function() {
   alert( this.value );
};
var foo = new Foo( 'bar' );
foo.alert(); // 'bar'

在传统 onevent 属性的代码中, this 引用接收事件的元素——但是只在属性中,而不在从属性调用的函数中:

<a href="#" id="test" onclick="clicked(this);">Test</a>
function clicked( it ) {
   alert( it.id );    // 'test'
   alert( this.id );   // undefined
   alert( this === window ); // true (什么?)
}

从第三个 alert() 中可以看到, this 实际上是函数中的 window 对象。由于历史原因,当直接调用函数(也就是说,不是作为对象方法调用)时, windowthis 的“默认”含义。

在jQuery事件处理程序中, this 是处理事件的DOM元素,所以 $(this) 是用于该DOM元素的一个jQuery包装器。这就是为什么在“问题”代码中 $(this).addClass() 能够按照预期工作的原因。

但是,代码接着调用 setTimeout() , setTimeout() 以直接函数调用的方式工作: this 指的是 window 对象。所以当代码调用 $(this).removeClass() 时,实际上试图从 window 对象中删除类!

为什么将 this 或者 $(this) 复制到一个局部变量中能够解决这个问题?JavaScript为参数和函数的局部变量创建了一个闭包。

闭包初看似乎很神秘,但实际上可以归纳为三条简单的原则:

  • 可以在JavaScript函数中嵌套另一个函数,嵌套可以为多级。
  • 函数不仅能读写自己的参数和局部变量,而且能读写嵌套函数中的变量。
  • 前一条原则始终有效,即使外部函数已经返回之后再调用内部函数也是如此(例如,时间处理程序或者 setTimeout() 回调)。

不管函数是命名的还是匿名的,上述原则对所有函数都适用。但是, this 不是函数参数或者局部变量——它是特殊的JavaScript关键字——所以这些原则不适用于它。通过将 this 的值复制到一个局部变量中,就能利用闭包使该值在任何嵌套函数中可用。