原文地址: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支持“逻辑短路”,所谓逻辑短路是指:

  1. 在”||” 运算中,第一个条件符合就结束判断。
  2. 在”&&”运算中,第一个条件不符合就结束判断。

因此,”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 杂谈之哪种写法你更喜欢?》最后一种“匿名函数法”的解释...相关推荐

  1. (转)javascript 杂谈之哪种写法你更喜欢?

    原文地址:http://www.cnblogs.com/baochuan/archive/2012/04/30/2473771.html 思维导图 介绍 老是在写js,你平时是怎么写你的js呢?更喜欢 ...

  2. 选项在哪_心理测试:4种高跟鞋,比较喜欢哪一种?测试出你对物的欣赏面

    心理测试:4种高跟鞋,比较喜欢哪一种?测试出你对物的欣赏面! A选项: 选项B: 选项C: 选项D: 您所想要的答案正在解析当中,请稍后--请勿走开哦! A选项答案:选择A选项的人,对事物的欣赏比较腹 ...

  3. 人工智能监考 VS 传统方式监考,你更喜欢哪一种?

    编译 | 禾木木 出品 | AI科技大本营(ID:rgznai100) 越来越多地大学和机构使用人工智能来监督学生参加考试. 这是未来的监考趋势吗? 由于目前这种方式越来越流行,世界各地的机构都迅速采 ...

  4. JavaScript 普通函数的三种写法

    第一种写法:不常用 //创建一个函数对象,较少使用//可以将要封装的代码以字符串的形式传递给构造函数var fun = new Function("console.log('hello,这是 ...

  5. Vue2基础-el与data的两种写法(HTML版)

    目录 一.el的2种写法 二.data的2种写法 三. 一个重要的原则 Vue2基础全套教程合集:点击跳转        Vue2高级全套教程合集:点击跳转 一.el的2种写法 new Vue时候配置 ...

  6. 从零学习Vue - 02模板语法、el与data两种写法、mvvm模型、数据代理

    root容器里的代码被称为模板,有了模板会有特殊的模板语法.Vue模板中语法有两大类,一类是插值语法,另一类是指令语法. 插值语法 功能:用于解析标签体内容.写法:{{xxx}},xxx为js表达式, ...

  7. mysql注释用处_mysql的注释有几种写法

    mysql的注释有几种写法 mysql的注释有3种,分别为:1.使用"#注释内容"进行的单行注释:2.使用"-- 注释内容"进行的单行注释,"--&q ...

  8. 我去,JS自执行匿名函数竟然有20几种写法!

    为什么80%的码农都做不了架构师?>>>    发现一个新的自执行写法: { var x; x=1; alert(x);} //2013-01-30 14:45:57 //五大类,2 ...

  9. python的for语句是否只有一种写法_跟老齐学Python之for循环语句

    废话少说,上干活. for的基本操作 for是用来循环的,是从某个对象那里依次将元素读取出来.看下面的例子,将已经学习过的数据对象用for循环一下,看看哪些能够使用,哪些不能使用.同时也是复习一下过往 ...

最新文章

  1. python制作动态条形图-python – 动态更新matplotlib中的条形图
  2. 怎样不让Dreamweaver中HTML源代码不自动换行??
  3. python中的静态方法如何调用_关于Python中如何使用静态、类、抽象方法的权威指南(译)...
  4. Struts2之Ognl
  5. 如何使得客户端和服务器端完美配合做IOS应用内付费
  6. 主人的C++桌上也没有这么好看的花朵了
  7. Springboot04整合Druid
  8. note2 android4.3,三星N7100/note2官方4.3原版线刷版N7100ZCUENB1
  9. MyEclipse10安装破解教程
  10. 某些型号的Comba和D-Link路由器存在管理员密码泄露漏洞
  11. FTP上传文件0字节问题
  12. SuperMap 基本概念
  13. 2022京东年货节全民炸年兽活动时间和玩法阶段
  14. 九、Unity编辑器开发之Gizmos
  15. Android中通过来电转移实现“电话已关机”,“此号码已停机”等
  16. 使用SVM/k-NN模型实现手写数字多分类 - 清华大学《机器学习实践与应用》22春-周作业
  17. 计算机突然断电后 硬盘中的数据,电脑突然断电对硬盘有影响吗?实测便知
  18. Java 9 模块化开发:核心原则与实践
  19. CCleaner的使用
  20. 应届生找嵌入式工作难吗?

热门文章

  1. 数据结构迷宫代码_数据结构课程设计——迷宫求解(二)
  2. Spring的加载机制导致不同SpringBoot启动方式下@Value注解失效
  3. 5u以太网用交换机连接电脑_干货丨如何用自己的电脑直接连接NUS打印机
  4. 【Redis】Redis 乐观锁
  5. 【mac】mac 安装nginx
  6. 【jmx】java jmx 获取 kafka topic的logStart LogEnd信息
  7. 【Kafka】Kafka Leader:none ISR 为空 消费超时
  8. 如何让JSON只从Model中输出一部分
  9. 79-Spark Standalone架构设计要点分析
  10. Spark的动态资源分配ExecutorAllocationManager