通过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系列(12) 变量对象(Variable Object)
Jan 16 Javascript
jQuery中dequeue()方法用法实例
Dec 29 Javascript
深入讲解AngularJS中的自定义指令的使用
Jun 18 Javascript
jQuery实现图片轮播效果代码(基于jquery.pack.js插件)
Jun 02 Javascript
Jquery揭秘系列:ajax原生js实现详解(推荐)
Jun 08 Javascript
jquery validation验证表单插件
Jan 07 Javascript
JS实现本地存储信息的方法(基于localStorage与userData)
Feb 18 Javascript
React Native之TextInput组件解析示例
Aug 22 Javascript
基于vue v-for 多层循环嵌套获取行数的方法
Sep 26 Javascript
浅谈Node框架接入ELK实践总结
Feb 22 Javascript
layui问题之模拟table表格中的选中按钮选中事件的方法
Sep 20 Javascript
vue 中使用print.js导出pdf操作
Nov 13 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
Re:从零开始的异世界生活 第2季 开播啦
2020/07/24 日漫
《PHP编程最快明白》第二讲 数字、浮点、布尔型、字符串和数组
2010/11/01 PHP
php下将多个数组合并成一个数组的方法与实例代码
2011/02/03 PHP
php中mt_rand()随机数函数用法
2014/11/24 PHP
PHP编程文件处理类SplFileObject和SplFileInfo用法实例分析
2017/07/22 PHP
YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例
2020/03/18 PHP
JS input 数字验证代码
2009/07/30 Javascript
JavaScript 学习笔记(十一)
2010/01/19 Javascript
基于jquery封装的一个js分页
2011/11/15 Javascript
XMLHttpRequest处理xml格式的返回数据(示例代码)
2013/11/21 Javascript
httpclient模拟登陆具体实现(使用js设置cookie)
2013/12/11 Javascript
NODE.JS加密模块CRYPTO常用方法介绍
2014/06/05 Javascript
用js提交表单解决一个页面有多个提交按钮的问题
2014/09/01 Javascript
微信小程序购物商城系统开发系列-工具篇的介绍
2016/11/21 Javascript
jQuery简单实现的HTML页面文本框模糊匹配查询功能完整示例
2018/05/09 jQuery
trackingjs+websocket+百度人脸识别API实现人脸签到
2018/11/26 Javascript
[56:00]DOTA2上海特级锦标赛主赛事日 - 4 胜者组决赛Secret VS Liquid第一局
2016/03/05 DOTA
[01:05:32]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#1COL VS Alliance第一局
2016/03/04 DOTA
python完成FizzBuzzWhizz问题(拉勾网面试题)示例
2014/05/05 Python
python 3.7.0 安装配置方法图文教程
2018/08/27 Python
Python 将Matrix、Dict保存到文件的方法
2018/10/30 Python
Python 绘制酷炫的三维图步骤详解
2019/07/12 Python
jupyter notebook 重装教程
2020/04/16 Python
Willer台湾:日本高速巴士/夜行巴士预约
2017/07/09 全球购物
一些PHP的面试题
2015/05/06 面试题
高级Java程序员面试题
2016/06/23 面试题
绩效工资分配方案
2014/01/18 职场文书
《我的信念》教学反思
2014/02/15 职场文书
项目施工员岗位职责
2014/03/09 职场文书
课前三分钟演讲稿
2014/04/24 职场文书
煤矿安全生产月活动总结
2014/07/05 职场文书
公务员年度考核个人总结
2015/02/12 职场文书
硕士学位申请报告
2015/05/15 职场文书
干货:如何写好工作计划!
2019/05/17 职场文书
详解MySQL中的主键与事务
2021/05/27 MySQL
Redis如何实现分布式锁
2021/08/23 Redis