【jquery源码】(1)开始学习源码之前需要解决的一些问题

前言:在这mvvm模式盛行的今天,很多人觉得没必要去了解jquery源码,而我并不认同以上的说法。jquery对javaScript进行了封装使其更加完善,jquery的源码中更是能看到对js原生方法的完美运用,还能学到很多没见过的操作JavaScript的技巧。简单的说,学习源码能让JavaScript使用基础更扎实。

学习jquery源码需解决的几个问题。

①、jquery是如何做到里面定义的变量不暴露在全局,而且只暴露出来一个$操作符跟一个jQuery给我们调用。

②、jquery是如何做到不运用到new就可以实例化jquery对象的。

③、jquery是如果做到链式操作的。


一、问题①

我们无法直接访问jquery里面定义的变量,但是通过$操作符或者jQuery就可以进行访问了。

(function(window,undefined){
	//第二个形参undefined是为了里面出现的变量名为undefined的变量值真的为undefined,而不是其他值
	var jQuery = function(){  //构造函数
		
	};  
	window.jQuery = window.$ = jQuery;	
})(window);

利用匿名函数自执行,来形成全局无法直接访问的函数作用域,然后将全局的window,通过传参的方式传入到该函数作用域中。最后通过window.jQuery = jQuery,window.$ = jQuery的方式,将jQuery构造函数暴露出去。这样我们就可以通过jQuery和$访问该函数作用域里变量了。


二、问题②

jquery是如何做到不运用到new就可以实例化jquery对象的。

function Person(name,age){         
	this.init(name,age);
};  
Person.prototype= {
	init: function(name,age){
		this.name = name;  
    	this.age = age;
	},
	sayName: function(){
		console.log('姓名: '+ this.name);	
	},
	sayAge: function(){
		console.log('年龄: '+ this.age);	
	}
};     
      
var nick = new Person('nick',18);  //实例化对象
nick.sayName();  
nick.sayAge();

JavaScript中实例化一个对象需要通过new一个构造函数的方式是实现。而在jquery中我们可以直接通过类似$('.box')的方式直接实例出一个jQuery对象,并通过$('.box').css()的方式直接调用对象方法。这是怎么做到的。

现在来模拟jQuert中实现不用new实例化对象的写法

(function(window,undefined){
	var jQuery = function(name,age){
		return new jQuery.prototype.init(name,age);	
	};
	
	jQuery.prototype = {
		init: function(name,age){
			this.name = name;  
    		this.age = age;	
		},
		sayName: function(){
			console.log('姓名: '+this.name);	
		},
		sayAge: function(){
			console.log('年龄: '+this.age);
		}	
	};
	jQuery.prototype.init.prototype = jQuery.prototype;
	
	window.jQuery = window.$ = jQuery;	
})( window );
var nick = $('nick',18);
nick.sayName();
nick.sayAge();
$('freddy',23).sayName();
$('freddy',23).sayAge();

输出结果:

这样也就实现了不用再外面用new就可以实例化对象了。其中比较抽象的就是

jQuery.prototype.init.prototype = jQuery.prototype;

了解过prototype也就知道,对象的实例化跟prototype原型密不可分。这里是把jQuery.prototype.init.protype的指向指回了jQuery.prototype。

我们在看回jquery源码中的写法

(function(window,undefined){
	var jQuery = function(selector, context){
		return new jQuery.fn.init(selector, context, rootjQuery);
	};
	jQuery.fn = jQuery.prototype = {
		init: function(selector, context, rootjQuery){
				
		}
	} 
	jQuery.fn.init.prototype = jQuery.fn;
	
	window.jQuery = window.$ = jQuery;	
})( window );

跟我们模拟的写法稍有不同的是,他让jQuery.fn = jQuert.prototype = {},让jQuery.fn指向了同一个原型对象,这样操作jQuery.fn等同于操作jQuery原型对象。


三、问题③

链式操作

(function(window,undefined){
	var jQuery = function(name,age){
		return new jQuery.prototype.init(name,age);	
	};
	
	jQuery.prototype = {
		init: function(name,age){
			this.name = name;  
    		this.age = age;	
		},
		sayName: function(){
			console.log('姓名: '+this.name);	
			return this;    //添加return this
		},
		sayAge: function(){
			console.log('年龄: '+this.age);
			return this;	//添加return this
		}	
	};
	jQuery.prototype.init.prototype = jQuery.prototype;
	
	window.jQuery = window.$ = jQuery;	
})( window );
var nick = $('nick',18);
nick.sayName().sayAge();
$('freddy',23).sayName().sayAge();
像这样,return this就好啦。

猜你喜欢

转载自blog.csdn.net/w390058785/article/details/80608041