jquery中变量拼接_1.jQuery⼯⼚函数加原型共享创建对象模式前⾔
⾸先声明⼀下,该⽂档⽤于对 jQuery 源码的讲解,对于学习原⽣ js 我们很多时候都不知道⾃⼰的定位到底是什么,掌握程度真的算得上是⼤神了吗?看源码是⼀种有效的⽅式来认清⾃⼰,向⼤佬学习的过程。
本专栏会依次循序渐进的讲解 jQuery 的源码。
cdt进⼊源码
( function( global, factory ) {
"u strict";
if ( typeof module === "object" && ports === "object" ) {
factory( global, true ) :
function( w ) {
if ( !w.document ) {
throw new Error( "jQuery requires a window with a document" );
}
return factory( w );
};
} el {
factory( global );
}
// Pass this if window is not defined yet
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
});
进⼊源码后最外层的框架就是这样了,可以看到整体是⼀个⾃执⾏函数
⾃执⾏函数,然后在函数体内做了⼀些判断运⾏环境的操作,以便于适⽤于Common.js 规范。
Common.js
可以看到如果是浏览器运⾏环境那么⾃执⾏的第⼆个参数的 noGlobal
undefined,翻到源码最下⾯可以看到:
noGlobal 参数是 undefined
if ( typeof noGlobal === "undefined" ) {door to door
window.jQuery = window.$ = jQuery;
}
return jQuery;
jQuery 的引⽤。
jQuery($$)的变量。拿到了内部的变量 jQuery
window 全局上定义⼀个 jQuery
这⾥如果是浏览器运⾏环境下就会向 window
jQuery 究竟是什么了,但是我们需要学习到的是,我们在⾃⼰写代码、造轮⼦的时候应该学或许你现在已经迫不及待的想看看 内部变量 jQuery
习这种模式,全部的业务逻辑写到了⼀个函数中,这样在库内部声明的变量就不会污染全局。最后为⽤户暴露出⼀个统⼀的接⼝jQuery。
——jQuery
jQuery 或者 $
$ 了。
这样我们就可以在外部直接使⽤ jQuery
jQuery 是什么束手无策英语
等等英语jQuery 这个内部的变量究竟是什么。
接下来就让我们再次进⼊源码,看看 jQuery
jQuery 的时候的⽤法:
在看之前,我门可以先来⼤胆的猜测⼀下。试想,我们在使⽤ jQuery
天然染发
$('div').css('background', 'pink');
这样简简单单的代码就可以获取到了页⾯中的所有 div 标签并设置粉⾊的背景⾊。
从这⾥我们可以看到我们拿到 $$ 变量是把它当作⼀个函数在调⽤,所以它可能是下⾯的写法:
// 写法1
var jQuery = function() {
};
// 写法2
function jQuery() {
}
jQuery 上⾯的⼀些属性或者⽅法,例如d(),对于以上两种⽅法,都可以实现,但是我认为第⼀种写法更好我们还可以使⽤到 jQuery
⼀些。
另外我们可以在控制台打印⼀下 $('div'):
new 操作符加构造函数来创建,
listen是什么意思
$(),⽅法会返回⼀个对象。在 javascript 创建对象需要使⽤ new
可以看到这其实是⼀个对象,也就是说调⽤ $()
new 关键字呢?
jQuery 就是⼀个构造函数,但是为什么这⾥并没有使⽤ new
我们可以先理解 jQuery
我们带着⾃⼰的揣测和疑问进⼊源码:
var jQuery = function( lector, context ) {
return new jQuery.fn.init( lector, context );
};
直到看到这⾥我们就⼀⽬了然,这不就是⼀个⼯⼚模式 吗?
⼯⼚模式
这⾥普及⼀个创建型的设计模式——⼯⼚模式。
⼯⼚模式就是允许我们使⽤函数返回值的形式构造⼀个对象,使⽤它就⼏点好处:
使⽤者不需要知道构造函数是谁
差不多英文
不需要使⽤ new 操作符
实现⼀个简易的⼯⼚模式:
function Person(name) {
this.name = name;
}
function createPerson(name) {
return new Person(name);
清华大学 在职研究生}
const person = createPerson('jerry');
console.log(person);
bbl
new 操作符。
from time to time可以看到我们在使⽤的时候并不知道内部的构造函数是谁,也并没有使⽤ new
内部实现
源码内部的真实的构造函数究jQuery 的源码,这个时候我们就已经知道了为什么我们在使⽤的时候会那么调⽤了。那么问题来了,源码内部的真实的构造函数究回到 jQuery
竟是谁呢?
我们看到⼯⼚函数的内部返回结果为 new jQuery.fn.init( lector, context );所以我们顺藤摸⽠,jQuery.fn ⼜是什么呢?
查找源码,我们可以看到:
jQuery.fn = jQuery.prototype = {
get: function () {},
each: function() {},
map: function() {}
// ...
};
也就是说 jQuery.fn 其实是拿到了 jQuery.prototype的引⽤,那么原型对象上的 init 函数⼜是什么呢?
var init = jQuery.fn.init = function( lector, context, root ) {
// 处理参数的代码
};
到这⾥⽬前的疑问就已经解决完了。
init 构造⽅法。
总结⼀下就是 jQuery
jQuery 原型对象上的 init
jQuery 实际是⼀个⼯⼚函数,内部实例化了 jQuery
这⾥你可能会有⼀个疑问,我们为什么不这样写:
var jQuery = function( lector, context ) {
return new jQuery( lector, context );
};
jQuery 的实例对象了吗?
我们这样,函数的返回值不就直接是⼀个 jQuery
new 操作符创建对象会发⽣什么:
事实上这样是会报错的,试想我们使⽤ new
创建⼀个对象
绑定 this 指向新创建的对象
执⾏构造函数内部的代码
使该对象的 _proto_ 属性指向构造函数的 prototype
出问题的是第三个环节,我们会执⾏该构造函数,那么如果直接 return new jQuery( lector, context );那么函数执⾏栈不就溢出了吗,所以就报错了。
共享原型
jQuery 的作者的这样的设计感动吃惊,那么我会告诉你,今天的主⾓才刚刚要来临了
如果你已经为 jQuery
jQuery.prototype 对象上有很多的⽅法:get,each,map等等。我们只是给 jQuery 的原型对象上添加了细⼼的我们已经发现了,在 jQuery.prototype
init 的实例对象也可以使⽤这些⽅法呢?我们百思不得其解,直到看到了这么⼀⾏代码:
这些⽅法 可是为什么上⾯的 init
init.prototype = jQuery.fn;
现在,你可以尖叫了
jQuery 的原型对象上添加⽅法,init 的实例对象都可以使⽤这些⽅法了。
这就是共享原型,这样设计之后,我们只需要为 jQuery
图解
通过这张图我相信你肯定可以更好的理解这⼀共享原型的设计了。