通过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 相关文章推荐
JS模拟多线程
Feb 07 Javascript
JS禁用浏览器退格键实现思路及代码
Oct 29 Javascript
JavaScript中操作字符串小结
May 04 Javascript
AngularJs expression详解及简单示例
Sep 01 Javascript
原生JS京东轮播图代码
Mar 22 Javascript
Angularjs中使用指令绑定点击事件的方法
Mar 30 Javascript
Vue自定义指令详解
Jul 28 Javascript
JavaScript中EventLoop介绍
Jan 22 Javascript
node静态服务器实现静态读取文件或文件夹
Dec 03 Javascript
JS实现横向轮播图(中级版)
Jan 18 Javascript
vue实现简单图片上传
Jun 30 Javascript
vue中v-model对select的绑定操作
Aug 31 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调用三种数据库的方法(1)
2006/10/09 PHP
PHP数据库操作三:redis用法分析
2017/08/16 PHP
PHP Laravel中的Trait使用方法
2019/01/20 PHP
Thinkphp5.0 框架使用模型Model添加、更新、删除数据操作详解
2019/10/11 PHP
PHP实现简单的协程任务调度demo示例
2020/02/01 PHP
JavaScript 无符号右移赋值操作
2009/04/17 Javascript
jQuery搜索子元素的方法
2015/02/10 Javascript
Javascript中使用A标签获取当前目录的绝对路径方法
2015/03/02 Javascript
JavaScript制作windows经典扫雷小游戏
2015/03/31 Javascript
JavaScript中constructor()方法的使用简介
2015/06/05 Javascript
JavaScript实现模仿桌面窗口的方法
2015/07/18 Javascript
基于bootstrap的选择框插件icheck
2016/12/23 Javascript
原生javascript移动端滑动banner效果
2017/03/10 Javascript
详解nodeJs文件系统(fs)与流(stream)
2018/01/24 NodeJs
webstorm+vue初始化项目的方法
2018/10/18 Javascript
浅谈Vue服务端渲染框架Nuxt的那些事
2018/12/21 Javascript
微信小程序云开发获取文件夹下所有文件(推荐)
2019/11/14 Javascript
javascript设计模式 ? 职责链模式原理与用法实例分析
2020/04/16 Javascript
微信小程序视频弹幕发送功能的实现
2020/12/28 Javascript
Python 自动安装 Rising 杀毒软件
2009/04/24 Python
Python脚本实现格式化css文件
2015/04/08 Python
python list是否包含另一个list所有元素的实例
2018/05/04 Python
Python利用splinter实现浏览器自动化操作方法
2018/05/11 Python
利用ImageAI库只需几行python代码实现目标检测
2019/08/09 Python
Django Session和Cookie分别实现记住用户登录状态操作
2020/07/02 Python
python3中编码获取网页的实例方法
2020/11/16 Python
HTML5 Canvas鼠标与键盘事件demo示例
2013/07/04 HTML / CSS
eDreams德国:南欧领先的在线旅游公司
2020/12/07 全球购物
为什么Runtime.exec(“ls”)没有任何输出?
2014/10/03 面试题
中英双版中文教师求职信
2013/10/27 职场文书
先进员工获奖感言
2014/08/14 职场文书
四风查摆问题及整改措施
2014/10/10 职场文书
先进教师个人事迹材料
2014/12/15 职场文书
导游带团欢迎词
2015/09/30 职场文书
社区宣传标语口号
2015/12/26 职场文书
MySQL 使用SQL语句修改表名的实现
2021/04/07 MySQL