(转)对《javascript 杂谈之哪种写法你更喜欢?》最后一种“匿名函数法”的解释...
原文地址:http://www.cnblogs.com/hkncd/archive/2012/05/04/2482064.html
前两天看了篇不错的关于javascript写法的文章。在评论里,不少人表示看不懂最后一种方法,作者也没详细说明,于是我顺势解说,算是沾点人气。
代码如上图,整体结构模仿jQuery,代码不长,知识点较多,信息量很大,我们分两部分,逐行解释。
第一部分
第一部分中,我们把extend相关的方法抽离,剩余代码如下:
(function () {var yQuery = (function () {var yQuery = function () {return yQuery.fn.init();};yQuery.fn = yQuery.prototype = {init: function () {return this;}};return yQuery;})();window.yQuery = window.$ = yQuery();})();
知识点1:无引用的匿名函数调用
(function() {})();
这种写法作用是声明并执行一个方法,等同于:
function Test() {}Test();
知识点2:属性变量无需声明
var obj = new Object();obj.name = "abc";
obj并没有name属性,但无需声明就可以使用,初始值为undefined。上例中yQuery.fn 就没有声明。
知识点3:{}二义性,相当于创建一个对象。
var obj = new Object(); var obj = { };
在js中,{}除了可作为复合语句边界以外,还有创建一个空对象的作用,因此上面这两句相同。而在例子中用到的情况如下:
{init: function () {return this;}};
这段代码猛一看像方法,实质是一个包含了init方法的对象,而方法中的this指向这个对象本身。
知识点4:连等表达式
var a = b = 1;
这个比较好理解,相当于对他们分别赋同一个值。在上例中,yQuery.fn就用到了这个写法。
知识点5:原型继承prototype
yQuery.fn = yQuery.prototype = {init: function () {return this;}};
例子中,通过连等分别对yQuery.fn和yQuery.prototype赋值给了同一个对象。而fn的作用只是一个别名,只为书写方便,重点是给prototype赋值,为什么要给它赋值?在本例中无法解释。
在jQuery中,init方法会返回不同对象,而本例中永远返回同一个对象,因此这里prototype没有多大意义。至于jQuery为什么要用prototype,算是题外话了,有兴趣的可点这里。
第一部分代码含义
这段代码第二行yQuery和第三行的yQuery是两个变量,因名字相同,所有很有迷惑性。整段代码意思就是:yQuery.prototype指向了一个包含init方法的对象,prototype有个别名fn,可通过yQuery.fn.init()返回这个对象,最后把这个对象赋值给window.$和window.yQuery属性。
第二部分
看完了第一部分,第二部分就相对简单了,代码如下:
yQuery.extend = yQuery.fn.extend = function () {var options, name, src, copy,target = arguments[0] || {},i = 1,length = arguments.length;if (length === i) {target = this;--i;}for (; i < length; i++) {if ((options = arguments[i]) != null) {for (name in options) {src = target[name];copy = options[name];if (src === copy) {continue;}if (copy!==undefined) {target[name] = copy;}}}}return target;};
知识点1:函数中的arguments变量
函数内部会自带一个arguments变量,该变量记录传入的参数,从左至右分别是arguments[0],arguments[1]等,js奇怪的地方在于,你声明了一个无参函数,在调用的时候依然可以传入参数,比如:
function NoArg() {console.log(arguments[0]);console.log(arguments[1]);console.log(arguments[2]);}NoArg(1, 2, "a");
该例NoArg调用时,会正常显示传入参数。
知识点2:结果类型不确定的逻辑运算
js中,所有类型都可以进行逻辑判断(true或false),js会将值转化为布尔值,但并不改变原值。如:
var str = "a";if(str) {}
此处的str为true,该特性与逻辑运算符”||”和”&&”结合形成了js一大特点,代码如下:
var str = "a"; var num = 1; var x = str || num; //x="a" var y = str && num; //y=1;
js支持“逻辑短路”,所谓逻辑短路是指:
- 在”||” 运算中,第一个条件符合就结束判断。
- 在”&&”运算中,第一个条件不符合就结束判断。
因此,”str || num”的str为true,则结束判断,返回str。”str&&num”的str为true,则继续判断num,num为true,则返回num。在本文案例中,有几个地方用到了这个特性:
target = arguments[0] || {}
容易看出,如果arguments[0]有值则返回该值,不然就通过{}返回一个空的对象。还有一处在图片中有,我文中没有打出来的代码:
$.ui = $.ui || { };
知识点3:数组方式访问对象属性
var obj = new Object(); obj.name = "a"; obj["name"] = "a";
最后两行代码等效。
第二部分代码含义
这部分代码可简单描述为:定义一个方法,将参数1之外的所有参数的属性成员赋值给参数1。我把循环部分修改一下,能更容易看懂,代码如下:
for (; i < length; i++) {if ((options = arguments[i]) != null) {for (var name in options) {if (options[name] !== undefined) {target[name] = options[name];}}}}
结语
js中有不少语法和运算符存在二义性,这导致js代码显的混乱难懂,所以不少人骂js是一个2B的语言,我觉得也不无道理。不过随着js的应用范围越来越广泛,终究避不开它,因此骂归骂,学还是要学的。
我是看了周爱民老师的《JavaScript语言精髓与编程实践(第2版)》后才算对js真正入门,饮水思源,推荐此书。
转载于:https://www.cnblogs.com/fcsh820/archive/2012/05/09/2491861.html
(转)对《javascript 杂谈之哪种写法你更喜欢?》最后一种“匿名函数法”的解释...相关推荐
- (转)javascript 杂谈之哪种写法你更喜欢?
原文地址:http://www.cnblogs.com/baochuan/archive/2012/04/30/2473771.html 思维导图 介绍 老是在写js,你平时是怎么写你的js呢?更喜欢 ...
- 选项在哪_心理测试:4种高跟鞋,比较喜欢哪一种?测试出你对物的欣赏面
心理测试:4种高跟鞋,比较喜欢哪一种?测试出你对物的欣赏面! A选项: 选项B: 选项C: 选项D: 您所想要的答案正在解析当中,请稍后--请勿走开哦! A选项答案:选择A选项的人,对事物的欣赏比较腹 ...
- 人工智能监考 VS 传统方式监考,你更喜欢哪一种?
编译 | 禾木木 出品 | AI科技大本营(ID:rgznai100) 越来越多地大学和机构使用人工智能来监督学生参加考试. 这是未来的监考趋势吗? 由于目前这种方式越来越流行,世界各地的机构都迅速采 ...
- JavaScript 普通函数的三种写法
第一种写法:不常用 //创建一个函数对象,较少使用//可以将要封装的代码以字符串的形式传递给构造函数var fun = new Function("console.log('hello,这是 ...
- Vue2基础-el与data的两种写法(HTML版)
目录 一.el的2种写法 二.data的2种写法 三. 一个重要的原则 Vue2基础全套教程合集:点击跳转 Vue2高级全套教程合集:点击跳转 一.el的2种写法 new Vue时候配置 ...
- 从零学习Vue - 02模板语法、el与data两种写法、mvvm模型、数据代理
root容器里的代码被称为模板,有了模板会有特殊的模板语法.Vue模板中语法有两大类,一类是插值语法,另一类是指令语法. 插值语法 功能:用于解析标签体内容.写法:{{xxx}},xxx为js表达式, ...
- mysql注释用处_mysql的注释有几种写法
mysql的注释有几种写法 mysql的注释有3种,分别为:1.使用"#注释内容"进行的单行注释:2.使用"-- 注释内容"进行的单行注释,"--&q ...
- 我去,JS自执行匿名函数竟然有20几种写法!
为什么80%的码农都做不了架构师?>>> 发现一个新的自执行写法: { var x; x=1; alert(x);} //2013-01-30 14:45:57 //五大类,2 ...
- python的for语句是否只有一种写法_跟老齐学Python之for循环语句
废话少说,上干活. for的基本操作 for是用来循环的,是从某个对象那里依次将元素读取出来.看下面的例子,将已经学习过的数据对象用for循环一下,看看哪些能够使用,哪些不能使用.同时也是复习一下过往 ...
最新文章
- python制作动态条形图-python – 动态更新matplotlib中的条形图
- 怎样不让Dreamweaver中HTML源代码不自动换行??
- python中的静态方法如何调用_关于Python中如何使用静态、类、抽象方法的权威指南(译)...
- Struts2之Ognl
- 如何使得客户端和服务器端完美配合做IOS应用内付费
- 主人的C++桌上也没有这么好看的花朵了
- Springboot04整合Druid
- note2 android4.3,三星N7100/note2官方4.3原版线刷版N7100ZCUENB1
- MyEclipse10安装破解教程
- 某些型号的Comba和D-Link路由器存在管理员密码泄露漏洞
- FTP上传文件0字节问题
- SuperMap 基本概念
- 2022京东年货节全民炸年兽活动时间和玩法阶段
- 九、Unity编辑器开发之Gizmos
- Android中通过来电转移实现“电话已关机”,“此号码已停机”等
- 使用SVM/k-NN模型实现手写数字多分类 - 清华大学《机器学习实践与应用》22春-周作业
- 计算机突然断电后 硬盘中的数据,电脑突然断电对硬盘有影响吗?实测便知
- Java 9 模块化开发:核心原则与实践
- CCleaner的使用
- 应届生找嵌入式工作难吗?
热门文章
- 数据结构迷宫代码_数据结构课程设计——迷宫求解(二)
- Spring的加载机制导致不同SpringBoot启动方式下@Value注解失效
- 5u以太网用交换机连接电脑_干货丨如何用自己的电脑直接连接NUS打印机
- 【Redis】Redis 乐观锁
- 【mac】mac 安装nginx
- 【jmx】java jmx 获取 kafka topic的logStart LogEnd信息
- 【Kafka】Kafka Leader:none ISR 为空 消费超时
- 如何让JSON只从Model中输出一部分
- 79-Spark Standalone架构设计要点分析
- Spark的动态资源分配ExecutorAllocationManager