jQuery对' this '变量做了一些神奇的事情吗?
Does jQuery do some magic with the `this` variable?
jQuery已经让我们习惯了以下的this
模式:
$(selector).each(function () {
// do something with `this`
// `this` iterates over the DOM elements inside `$(selector)`
});
根据这个Crockford谈话(大约15分钟),不使用new
运算符调用的函数中this
的值是全局对象,除了ES5严格模式,在这种情况下它是undefined
。
jQuery做一些魔术与this
得到它以外的东西,而不是全局对象?请指出源代码的具体行
jQuery使用100%非魔幻的Function.call
方法来调用具有特定this
的回调。
根据您的使用情况进行裁剪和改写:
jQuery.each = jQuery.fn.each = function( object, callback ) {
for ( var i = 0, length = object.length ; i < length; i++ ) {
if ( callback.call( object[ i ], i, object[ i ] ) === false ) {
break;
}
}
return object;
};
这是重要的部分:callback.call
.
孩子,是时候满足this
值了。this
有一个名称,它准确地指出了它所引用的容器。this
有几个可能的值
注意:因为它的名字,this
是一个很难谈论的值。因此,每当在代码注释或代码解释中看到self
(工作名)这个词时,它指的是this
的值。
var o = {
log : function () {
console.log( this );
}
};
o.log(); //will log the object o
function log () {
console.log( this );
}
//the default enclosing object is the global object - window
//this is the behaviour you observed in Crockford's talk
log();
//the self value is not set in stone. it is evaluated when the function is called
var grass = {
log : o.log,
color : 'purple'
};
grass.log(); //will log the object grass
//this is different from languages where self is static. in such languages, doing
// grass.log() would've logged the original object, o, but since self is evaluated
// at runtime, it is set to the now containing object - grass
我们在日常生活中看到的一种现象是变异的self
。当我看到一个泥鳅并大喊"这是蓝色的!"时,我并不是指我自己,尽管我的蓝色色调。相反,我宣布了this
的新值是谁(通过指向它)。这样的事情可以在js中完成,这就是在jQuery.each
中发生的事情。
是时候会见Function.prototype.apply
和Function.prototype.call
了。他们的行为最好通过一个例子来观察:
grass.speak = function ( message ) {
//a philosophical conundrum: how does grass talk?
console.log( this.color + ' ' + message );
};
grass.speak( ' fruit' ); //will log "blue fruit"
var ultraGrass = {
color : 'maroon'
};
grass.speak.call( ultraGrass, ', hijacked!' ); //will log "maroon, hijacked!"
Function.prototype.call
(从现在开始我就叫它call
。明白了吗?call…call…没关系)接受两个形参:一个thisArg
和一个变长形参列表。
call
和apply
使用指定的self
值(第一个参数)和参数列表(其余参数为call
,第二个参数为apply
)调用函数
Function.prototype.call( thisArg, arg0, arg1, arg2, ... );
Function.prototype.apply( thisArg, [arg0, arg1, arg2, ...] );
下面是一个更传统的例子:
function average () {
console.log( this ); //to see what call and apply actually do
for ( var i = 0, sum = 0, len = arguments.length; i < len; i++ ) {
sum += arguments[ i ];
}
return sum / ( len || 1 ); //don't want to divide by zero!
}
average( 1, 2, 3, 4, 5 ); //will log the global object, and return 3
average.call( grass, 1, 2, 3, 4, 5 ); //will log the grass object, and return 3
average.apply( grass, [1, 2, 3, 4, 5] ); //will do the same as above
log.call( ultraGrass ); //will log ultraGrass
log.apply( ultraGrass ); //will also log ultraGrass
call
和apply
之间的唯一区别是apply需要一个参数数组,而call使用第一个参数之后传递给它的所有参数作为参数。
返回到原来的jQuery代码:
callback.call( object[ i ], i, object[ i ] )
调用callback
函数:
-
this
设置为object[ i ]
, - 两个参数:
i
和object[ i ]
查看更多信息:
- 申请并调用MDN
- 在ES5规范 中应用和调用
这只是普通的javascript调用和应用
相关部分来自jQuery源码:
if ( isObj ) {
for ( name in object ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
} else {
for ( ; i < length; ) {
if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
break;
}
}
}
callback
指的是用.call
调用的函数:
function asd(){
alert( this.i ); // 3
}
asd.call( {i: 3} );
- $(this).prop('property') vs. this.property
- Twitter Bootstrap typeahead:使用“this”获取上下文/调用元素
- 在另一个函数中使用变量this
- this.router在AngularJS 2中未定义
- reactjs this.refs vs document.getElementById
- JavaScript 中的嵌套函数和 “this” 关键字
- React+Meteor:this.ops返回未定义
- javascript中对象构造函数中的var属性与this.properties
- 函数中this和var之间的区别
- jQuery(this).Pparent().Pparente().Prent().find()在iPad上不起作用
- Understanding Javascript scope with "var that = this&qu
- 定义this.properties或objectName.properties的javascript JSON对象
- Object.prototype using 'this'
- 在JavaScript类型的函数中避免self-this
- 如何使用(this)访问Angular 2 http rxjs catch函数中的对象属性
- Javascript 对象和 this 关键字
- jQuery使用ajax自动完成问题-TypeError:this.source不是函数
- reactjs无法将this.pops传递到react图表列表中
- 为什么在这种情况下,“This”确实充当javascript函数中的私有成员
- jQuery对' this '变量做了一些神奇的事情吗?