为什么这个而不是jQuery插件中的$(this)

文档告诉我们:

假设我们想要创建一个插件,使一组检索到的元素中的文本变为绿色。 我们所要做的就是在$ .fn中添加一个名为greenify的函数,它就像任何其他jQuery对象方法一样可用。

$.fn.greenify = function() { this.css( "color", "green" ); }; $( "a" ).greenify(); // Makes all the links green. 

请注意,要使用.css(),另一种方法,我们使用它,而不是$(this)。 这是因为我们的greenify函数是与.css()相同的对象的一部分。

我不明白最后一段。 该function传递给this什么? 为什么不用$(this)来引用jQuery对象? 我们不是使用$(el).css()来正常设置jQuery中的CSS吗? 那么为什么不在插件中呢?

让我们试着看一下:

让我们尝试生成一个非常简化的版本库,比如jQuery,并将其命名为microM

 (function(global) { //function analog jQuery var microM = function(context) { return new microM.fn.init(context); } //init prototype microM.fn = microM.prototype = { version: '0.0.0.1', constructor: microM }; //function for initialize context var init = microM.fn.init = function(context) { if (context instanceof microM) context = microM.extend([], context.context); this['context'] = [].concat(context); return this; }; init.prototype = microM.fn; //add function extend to prototype and as static method microM.extend = microM.fn.extend = function() { if (arguments.length == 2) { var target = arguments[0], source = arguments[1]; } else { var target = this, source = arguments[0]; } for (var key in source) { target[key] = source[key]; } return target; } //extend microM prototype with a few simple function microM.fn.extend({ min: function() { return Math.min.apply(Math, this.context); }, max: function() { return Math.max.apply(Math, this.context); }, pow: function(exponent) { for (var i = 0, len = this.context.length; i < len; i++) { this.context[i] = Math.pow(this.context[i], exponent); } return this; }, get: function() { return microM.extend([], this.context); }, map: function(callback) {//a function that takes a callback var result = []; for (var i = 0, len = this.context.length; i < len; i++) { var callbackResult = callback.call(this.context[i], this.context[i], i); if (callbackResult instanceof microM) result = result.concat(callbackResult.get()); else result = result.concat(callbackResult); } return microM(result); } }); //looks a like jQuery :-) global.microM = microM; })(window); 

所以我们有一个最简单的lib看起来像jQuery。 现在我们想要添加“插件”,例如函数square

就像在jQuery中一样,我们将它添加到原型中,或者在我们的例子中将fn与原型相同:

 microM.fn.square = function() { return this.pow(2); } 

在这里我们可以直接从这里调用pow ,因为在这种情况下,我们的microM实例和microM.prototype的所有函数都可以直接使用;

但是当我们调用map函数在回调内部进行回调时, 将是具体元素,例如Number原语,因为我们称它为

 callback.call(this.context[i], this.context[i], i); 

调用函数中的第一个参数 - 是thisArg

可能下面的代码片段可以清楚地说明我的混乱解释:-)

 (function(global) { var microM = function(context) { return new microM.fn.init(context); } microM.fn = microM.prototype = { version: '0.0.0.1', constructor: microM }; var init = microM.fn.init = function(context) { if (context instanceof microM) context = microM.extend([], context.context); this['context'] = [].concat(context); return this; }; init.prototype = microM.fn; microM.extend = microM.fn.extend = function() { if (arguments.length == 2) { var target = arguments[0], source = arguments[1]; } else { var target = this, source = arguments[0]; } for (var key in source) { target[key] = source[key]; } return target; } microM.fn.extend({ min: function() { return Math.min.apply(Math, this.context); }, max: function() { return Math.max.apply(Math, this.context); }, pow: function(exponent) { for (var i = 0, len = this.context.length; i < len; i++) { this.context[i] = Math.pow(this.context[i], exponent); } return this; }, get: function() { return microM.extend([], this.context); }, map: function(callback) { var result = []; for (var i = 0, len = this.context.length; i < len; i++) { var callbackResult = callback.call(this.context[i], this.context[i], i); if (callbackResult instanceof microM) result = result.concat(callbackResult.get()); else result = result.concat(callbackResult); } return microM(result); } }); global.microM = microM; })(window); microM.fn.printTo = function(id, descr) { document.getElementById(id).innerHTML += (descr ? descr + ": " : "") + JSON.stringify(this.get()) + '
'; return this; } microM.fn.square = function() { return this.pow(2); } var t = microM([2, 3, 4]).printTo('res', 'initial'); t.square().printTo('res', 'square') .map(function(el) { return microM(this + 10).square(); }).printTo('res', 'mapped') .map(function(el) { return this instanceof Number; }).printTo('res', 'inside map: this instanceof Number');
 

我们不是使用$(el).css()来正常设置jQuery中的CSS吗?

是的,在元素的上下文中。

然而在

 $.fn.greenify = function() { // 'this' is a jQuery object at this point - with all the jQuery functions this.css( "color", "green" ); }; 

greenify具有 css函数的同一对象的一部分。

在其他地方,有一个

 $.fn.css = function() { ... }; 

cssgreenify都是prototype一部分( $ .fn

看jQuery:’$(this)’和’this’之间有什么区别? 和https://remysharp.com/2007/04/12/jquerys-this-demystified