jQuery的所有代码放在了自调用的匿名函数中,防止命名污染
(function( window, undefined ) {
------
})( window );
我们在使用$("div")获取Dom元素,看起来就像是调了一个普通的函数,每次调用jQuery就会实例化一个对象
一般访问构造函数中的方法是这样操作,代码如下:
function jQuery(selector) {
this.html= function () {
console.log("我是绿豆糕");
}
}
new jQuery("div").html();
上边代码每次访问方法都要new一下,而我们看到的jQuery是这样的方式调用的jQuery("div").html(),怎么才能达到这样的效果呢? 想一想....
应该是jQuery内部帮我们实现了,调用jQuery函数的时候,返回值就应该是一个实例对象
function jQuery(selector) {
this.html= function () {
console.log("我是绿豆糕");
}
return new jQuery(selector);
}
jQuery("div").html();
这样做思路没有问题,让我们愉快的运行一下
糟糕.....整成堆栈溢出了,原因是new jQuery(),出现自己调用自己,发生递归却没有结束条件,这可咋整
其实这个问题jQuery内部的实现方式却相当高明
//闭包环境,防止与外部命名污染
(function (window, undefined) {
var jQuery = function (selector) {
//返回init构造函数的实例
return new jQuery.prototype.init(selector);
}
jQuery.prototype = {
constructor: jQuery,
init: function (selector) {
},
html: function () {
console.log("我是绿豆糕");
}
}
//init的原型指向jQuery的原型,这样我们就能访问jQuery原型中的方法了
jQuery.prototype.init.prototype = jQuery.prototype;
jQuery("div").html();
//导出接口,外部就可以访问了,这也是为什么我们用$("div")也能得到Dom元素
window.jQuery = window.$ = jQuery;
})(window)
调用jQuery函数返回的是return new jQuery.prototype.init(selector),但是为什么html方法不在init构造函数内部也能调用成功,打印出"我是绿豆糕"呢?
原因是执行了这行代码
jQuery.prototype.init.prototype = jQuery.prototype;
init里面的this,受制于作用域的限制,访问不到jQuery.prototype其它的属性
jQuery内部的一句'jQuery.fn.init.prototype=jQuery.fn'
将init的原型指向了jQuery的原型,这样一来,jQuery产生的实例对象就能够访问jQuery原型上的属性了
jQuery的原型中有html方法,这样init的实例也能访问了,因为原型继承
源码中jQuery.fn是啥? 实际上就是jQuery.prototype
jQuery.fn = jQuery.prototype = {
......
}
jQuery.fn.init.prototype = jQuery.fn;
等效于我们刚才分析的这句
jQuery.prototype.init.prototype = jQuery.prototype;