jq整体是一个立即执行函数。
思考问题:如何封闭作用域,如何暴露变量,无new构造,链式调用(关键句:你是我爸爸,我也是你爸爸),公有原型思想
思考问题一:封闭作用域
立即执行函数:通过定义一个匿名函数,创建了一个新的函数作用域,相当于创建了一个“私有”的命名空间,该命名空间的变量和方法,不会破坏污染全局的命名空间。
思考问题二:jq实现变量暴露在全局(例如$.(xxx))
(
function () {
//立即执行函数私有化变量,防止与js代码之间相互变量的污染;
var
a =
13;
unction
jQuery(
str) {
console.
log(
str);
console.
log(
a);
}
window.
$ =
window.
jQuery =
jQuery;
//暴露jQuery,$;
}());
jQuery(
'lalala');
//这个时候我们可以全局直接用jQuery()调用里面的方法;
此时若是想访问全局对象,将全局对象以参数形式传进去即可。
(
function(
window,
undefind){
//jQuery code
}(
window))
其中window即是全局对象。作用域隔离非常重要,是一个JS框架必须支持的功能,jQuery被应用在成千上万的JavaScript程序中,必须确保jQuery创建的变量不能和导入他的程序所使用的变量发生冲突。
思考问题三:无new构造实现(将方法写在jq的原型上)
function
jQuery(
str) {
return
new
jQuery.
prototype.
init(
str)
}
jQuery.
fn =
jQuery.
prototype = {
init
:
function (str) {
console.
log(
'init');
},
html
:
function (str) {
console.
log(
'html')
},
css
:
function (str) {
console.
log(
'css')
}
}
jQuery();
创建一个jq函数,里面返回他原型链的属性(经过new出来的)
思考问题四:链式调用(关键点在返回值和原型继承)
function
jQuery(
str) {
jQuery.
prototype.
init.
prototype =
jQuery.
prototype;
return
new
jQuery.
prototype.
init(
str);
}
jQuery.
fn =
jQuery.
prototype = {
init
:
function () {
console.
log(
'init');
return
this;
},
html
:
function () {
console.
log(
'html');
return
this;
},
css
:
function () {
console.
log(
'css');
return
this;
}
}
jQuery().
html().
css()
实现链式调:
执行jQuery()函数,实际是执行了jQuery原型上的init属性(属性值为函数)。在后面继续调用htnl和css方法,这里会有一个问题。因为html和css是jQuery原型上的属性不是init属性上的属性,所以这里我们可以把init原型链的指向给修改了,实现了把jQuery上的方法挂到init上。
当然,我们调用完init属性后,需要把init给返回(jQuery().html()--->init().html)
function
jQuery(
str) {
jQuery.
prototype.
init.
prototype =
jQuery.
prototype;
return
new
jQuery.
prototype.
init(
str);
}
jQuery.
fn =
jQuery.
prototype = {
init
:
function () {
console.
log(
'init');
console.
log(
this);
return
this;
},
html
:
function () {
console.
log(
'html')
console.
log(
this);
return
this;
},
css
:
function () {
console.
log(
'css')
console.
log(
this);
return
this;
}
}
jQuery().
html().
css()
可以执行以上代码。打印出来的this值为init()这个函数方法。
通过以上,实现了链式调用(核心在于入口函数init对jQuery原型的继承,和返回值的设定。)