通过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 相关文章推荐
javascript替换已有元素replaceChild()使用介绍
Apr 03 Javascript
用简洁的jQuery方法toggleClass实现隔行换色
Oct 22 Javascript
45个JavaScript编程注意事项、技巧大全
Feb 11 Javascript
Bootstrap多级导航栏(级联导航)的实现代码
Mar 08 Javascript
简单的js计算器实现
Oct 26 Javascript
Bootstrap CSS组件之下拉菜单(dropdown)
Dec 17 Javascript
Vuejs 组件——props数据传递的实例代码
Mar 07 Javascript
JavaScript 过滤关键字
Mar 20 Javascript
对Vue2 自定义全局指令Vue.directive和指令的生命周期介绍
Aug 30 Javascript
Vue动态创建注册component的实例代码
Jun 14 Javascript
layui的表单提交以及验证和修改弹框的实例
Sep 09 Javascript
react实现复选框全选和反选组件效果
Aug 25 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
php4的session功能评述(二)
2006/10/09 PHP
php数组相加 array(“a”)+array(“b”)结果还是array(“a”)
2012/09/19 PHP
简单的cookie计数器实现源码
2013/06/07 PHP
php中运用http调用的GET和POST方法示例
2014/09/29 PHP
基于ThinkPHP+uploadify+upload+PHPExcel 无刷新导入数据
2015/09/23 PHP
php使用preg_match()函数验证ip地址的方法
2017/01/07 PHP
PHP实现数组转JSon和JSon转数组的方法示例
2018/06/14 PHP
php实现 master-worker 守护多进程模式的实例代码
2019/07/20 PHP
建立良好体验度的Web注册系统ajax
2007/07/09 Javascript
jquery蒙版控件实现代码
2010/12/08 Javascript
jquery提交form表单时禁止重复提交的方法
2014/02/13 Javascript
JS实现鼠标经过好友列表中的好友头像时显示资料卡的效果
2014/07/02 Javascript
Javascript基础教程之break和continue语句
2015/01/18 Javascript
简介JavaScript中Boolean.toSource()方法的使用
2015/06/05 Javascript
JavaScript学习笔记之检测客户端类型是(引擎、浏览器、平台、操作系统、移动设备)
2015/12/03 Javascript
JS中生成随机数的用法及相关函数
2016/01/09 Javascript
Vue.js第一天学习笔记(数据的双向绑定、常用指令)
2016/12/01 Javascript
vue实现列表的添加点击
2016/12/29 Javascript
详解webpack+gulp实现自动构建部署
2017/06/29 Javascript
JS实现定时任务每隔N秒请求后台setInterval定时和ajax请求问题
2017/10/15 Javascript
全面介绍vue 全家桶和项目实例
2017/12/27 Javascript
Vue 指令实现按钮级别权限管理功能
2019/04/23 Javascript
Anaconda下配置python+opencv+contribx的实例讲解
2018/08/06 Python
Python设计模式之职责链模式原理与用法实例分析
2019/01/11 Python
python自定义时钟类、定时任务类
2021/02/22 Python
python实现高斯(Gauss)迭代法的例子
2019/11/20 Python
Django自带的加密算法及加密模块详解
2019/12/03 Python
基于python实现获取网页图片过程解析
2020/05/11 Python
python实现AdaBoost算法的示例
2020/10/03 Python
Python实现迪杰斯特拉算法并生成最短路径的示例代码
2020/12/01 Python
科颜氏香港官方网店:Kiehl’s香港
2021/03/07 全球购物
医药类个人求职的自我评价
2014/02/12 职场文书
高中生学期学习自我评价
2014/02/24 职场文书
Python中Permission denied的解决方案
2021/04/02 Python
python 对图片进行简单的处理
2021/06/23 Python
mysql聚集索引、辅助索引、覆盖索引、联合索引的使用
2022/02/12 MySQL