通过jQuery源码学习javascript(二)


Posted in Javascript onDecember 27, 2012

巧妙1:函数

在javascript代码中函数是个不可多得的人才。

♥ 它可以归置代码段,封装相对独立的功能。

♥ 它也可以实现类,注入OOP思想。

jQuery就是一个函数,你也可以把它当成类(呵呵,本身就是类)。

(function(){ 
var jQuery = function() { 
// 函数体 
} 
window.jQuery = window.$ = jQuery; 
})(); 
console.log(jQuery);

通过jQuery源码学习javascript(二)
上面的空函数就是所谓的构造函数,构造函数在面向对象语言中是类的一个基本方法。

巧妙2:扩展原型

何为原型对象?我给出一篇博文大家可以去了解一下https://3water.com/article/32857.htm。

javascript为所有函数绑定一个prototype属性,由这个属性指向一个原型对象。我们在原型对象中定义类的继承属性和方法等。

原型对象是javascript实现继承的基本机制。

(function(){ 
var jQuery = function() { 
// 函数体 
} 
jQuery.fn = jQuery.prototype = { 
// 扩展原型对象 
jquery: "1.8.3", 
test: function() { 
console.log('test'); 
} 
} 
window.jQuery = window.$ = jQuery; 
})(); (new jQuery()).test();

巧妙3:使用工厂方法来创建一个实例

上面的方法必须使用下面的方法才能进行调用,这样就会产生很多对象,从而浪费内存消耗。

(new jQuery()).test();

jQuery源码使用了很柔和的方法,也是大家比较熟悉的工厂方法,进行调用。

(function(){ 
var jQuery = function() { 
// 函数体 
return jQuery.fn.init(); 
} 
jQuery.fn = jQuery.prototype = { 
// 扩展原型对象 
jquery: "1.8.3", 
init: function() { 
return this; 
}, 
test: function() { 
console.log('test'); 
} 
} 
window.jQuery = window.$ = jQuery; 
})(); 
jQuery().test();

通过jQuery源码学习javascript(二)

假想1:让jQuery函数体直接返回该对象——我用this
(function(){ 
var jQuery = function() { 
return this; 
} 
jQuery.fn = jQuery.prototype = { 
// 扩展原型对象 
jquery: "1.8.3", 
test: function() { 
console.log('test'); 
} 
} 
window.jQuery = window.$ = jQuery; 
})(); 
console.log(jQuery());

输出结果

通过jQuery源码学习javascript(二)

发现这里的this指向Window对象。


假想2:让jQuery函数体直接返回类的实例。

(function(){ 
var jQuery = function() { 
return new jQuery(); 
} 
jQuery.fn = jQuery.prototype = { 
// 扩展原型对象 
jquery: "1.8.3", 
test: function() { 
console.log('test'); 
} 
} 
window.jQuery = window.$ = jQuery; 
})(); 
console.log(jQuery());

输出结果

通过jQuery源码学习javascript(二)

发现上面是一个递归死循环,出现内存外溢。

巧妙4:分隔作用域

思考1:init()方法返回的this作用域是什么?

(function(){ 
var jQuery = function() { 
// 函数体 
return jQuery.fn.init(); 
} 
jQuery.fn = jQuery.prototype = { 
// 扩展原型对象 
jquery: "1.8.3", 
init: function() { 
this.init_jquery = '2.0'; 
return this; 
} 
} 
window.jQuery = window.$ = jQuery; 
})(); 
console.log(jQuery().jquery); 
console.log(jQuery().init_jquery);

输出结果
通过jQuery源码学习javascript(二)

init()方法中的this作用域:this关键字引用了init()函数作用域所在的对象,同时也能够访问上一级对象jQuery.fn对象的作用。——这种思路会破坏作用域的独立性,对于jQuery框架来说,很可能造成消极影响。

思考2:怎么把init()中的this从jQuery.fn对象中分隔出来?——实例化init初始化类型。

(function(){ 
var jQuery = function() { 
// 函数体 
return new jQuery.fn.init(); 
} 
jQuery.fn = jQuery.prototype = { 
// 扩展原型对象 
jquery: "1.8.3", 
init: function() { 
this.init_jquery = '2.0'; 
return this; 
} 
} 
window.jQuery = window.$ = jQuery; 
})(); 
console.log(jQuery().jquery); 
console.log(jQuery().init_jquery);

输出结果
通过jQuery源码学习javascript(二)
通过实例化init()初始化类型,限定了init()方法里的this,只在init()函数内活动,不让它超出范围。

巧妙5:原型传递

思考1:在巧妙4中,我们把init()中的this从jquery.fn对象中分隔出来。那我们如何能做到保证“巧妙4”的基础上,还能访问jQuery原型对象呢?——原型传递。

让jQuery的原型对象覆盖init()构造器的原型对象。

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

全部代码:
(function(){ 
var jQuery = function() { 
// 函数体 
return new jQuery.fn.init(); 
} 
jQuery.fn = jQuery.prototype = { 
// 扩展原型对象 
jquery: "1.8.3", 
init: function() { 
this.init_jquery = '2.0'; 
return this; 
} 
} 
jQuery.fn.init.prototype = jQuery.fn; 
window.jQuery = window.$ = jQuery; 
})(); 
console.log(jQuery().jquery); 
console.log(jQuery().init_jquery);

输出结果

通过jQuery源码学习javascript(二)

妙棋

把init()对象的prototype指针指向jQuery.fn。——这样init()里的this继承了jQuery.fn原型对象定义的方法和属性。

总结

感谢博友的留言,尤其是puni ,给我介绍了一本不错的书。如果大家能补充一下,那就再好不过了。

Javascript 相关文章推荐
如何让div span等元素能响应键盘事件操作指南
Nov 13 Javascript
原生javascript实现图片无缝滚动效果
Feb 12 Javascript
three.js实现围绕某物体旋转
Jan 25 Javascript
微信小程序 定位到当前城市实现实例代码
Feb 23 Javascript
详解Angular路由 ng-route和ui-router的区别
May 22 Javascript
jQuery获取table表中的td标签(实例讲解)
Jul 28 jQuery
详解Vue2中组件间通信的解决全方案
Jul 28 Javascript
详解利用Angular实现多团队模块化SPA开发框架
Nov 27 Javascript
JS求Number类型数组中最大元素方法
Apr 08 Javascript
微信小程序实现无限滚动列表
May 29 Javascript
js面向对象之实现淘宝放大镜
Jan 15 Javascript
在vue中使用vant TreeSelect分类选择组件操作
Nov 02 Javascript
js 判断一个元素是否在页面中存在
Dec 27 #Javascript
通过jQuery源码学习javascript(一)
Dec 27 #Javascript
Eval and new funciton not the same thing
Dec 27 #Javascript
Javascript图像处理—虚拟边缘介绍及使用方法
Dec 27 #Javascript
JS 添加网页桌面快捷方式的代码详细整理
Dec 27 #Javascript
JavaScript初学者应注意的七个细节详细介绍
Dec 27 #Javascript
圣诞节Merry Christmas给博客添加浪漫的下雪效果基于jquery实现
Dec 27 #Javascript
You might like
PHP+Mysql日期时间如何转换(UNIX时间戳和格式化日期)
2012/07/15 PHP
浅谈discuz密码加密的方式
2014/05/22 PHP
php实现专业获取网站SEO信息类实例
2015/04/02 PHP
js变量作用域及可访问性的探讨
2006/11/23 Javascript
js 禁用只读文本框获得焦点时的退格键
2010/04/25 Javascript
jquery创建表格(自动增加表格)代码分享
2013/12/25 Javascript
理运用命名空间让js不产生冲突避免全局变量的泛滥
2014/06/15 Javascript
cocos2dx骨骼动画Armature源码剖析(一)
2015/09/08 Javascript
jquery层级选择器(匹配父元素下的子元素实现代码)
2016/09/05 Javascript
使用JS代码实现点击按钮下载文件
2016/11/12 Javascript
Angularjs分页查询的实现
2017/02/24 Javascript
五步轻松实现zTree的使用
2017/11/01 Javascript
JS中双击和单击事件冲突的解决方法
2018/04/09 Javascript
浅谈webpack-dev-server的配置和使用
2018/05/17 Javascript
详解微信小程序实现WebSocket心跳重连
2018/07/31 Javascript
nodejs之koa2请求示例(GET,POST)
2018/08/07 NodeJs
使用form-create动态生成vue自定义组件和嵌套表单组件
2019/01/18 Javascript
Js和VUE实现跑马灯效果
2020/05/25 Javascript
[02:55]2018DOTA2国际邀请赛勇士令状不朽珍藏Ⅲ饰品一览
2018/08/01 DOTA
老生常谈Python序列化和反序列化
2017/06/28 Python
Python Numpy:找到list中的np.nan值方法
2018/10/30 Python
python 判断linux进程,并杀死进程的实现方法
2019/07/01 Python
详解Python Matplotlib解决绘图X轴值不按数组排序问题
2019/08/05 Python
python3.7 利用函数os pandas利用excel对文件名进行归类
2019/09/29 Python
使用Python给头像加上圣诞帽或圣诞老人小图标附源码
2019/12/25 Python
Python字符串hashlib加密模块使用案例
2020/03/10 Python
Python如何使用ElementTree解析xml
2020/10/12 Python
使用CSS3代码绘制可爱的Hello Kitty猫
2016/08/03 HTML / CSS
美国婴儿和儿童家具网上商店:ABaby.com
2018/07/02 全球购物
铭立家具面试题
2012/12/06 面试题
领导干部培训感言
2014/01/23 职场文书
高三自我评价
2014/02/01 职场文书
2015年消防工作总结
2015/04/24 职场文书
卫生院义诊活动总结
2015/05/07 职场文书
小学2016年第十八届推普周活动总结
2016/04/05 职场文书
python基于tkinter实现gif录屏功能
2021/05/19 Python