谈谈JavaScript中function多重理解


Posted in Javascript onAugust 28, 2015

JavaScript 中的 function 有多重意义。它可能是一个构造器(constructor),承担起对象模板的作用; 可能是对象的方法(method),负责向对象发送消息。还可能是函数,没错是函数,和对象没有任何关系独立存在的可以被调用的函数。

由于语言设计者的妥协,在 JavaScript 加入了一些 class 相关的特性,以使 JavaScript 看起来确实象 Java,可以 “面向对象”。虽然 JavaScript 添加了 new 和 this, 但却没有 class (ES已加)。最后 function 临时担负起 class 的任务。

语义1:作为构造器的 function

/**
 * 页签
 *
 * @class Tab
 * @param nav {string} 页签标题的class
 * @param content {string} 页面内容的class
 *
 */
function Tab(nav, content) {
  this.nav = nav;
  this.content = content;
}
Tab.prototype.getNav = function() {
  return this.nav;
};
Tab.prototype.setNav = function(nav) {
  this.nav = nav;
};
Tab.prototype.add = function() {
};
// 创建对象
var tab = new Tab('tab-nav', 'tab-content');

这里定义了一个类 Tab,创建了一个对象 tab。以上使用了 function ,this, new。this, new 是常见的面向对象语言中的关键字, 这里的 function 则担负传统面向对象语言中的 class 作用。当然这时候标识符的命名一般遵循 “首字母大写” 规则。

语义2:作为对象方法的 function

由于 JavaScript 中无需类也可以直接创建对象,因此有两种方式给对象添加方法。第一种先定义类,方法挂在原型上,如上例的 Tab,原型上有 getNav、setNav 和 add 方法。以下还有一种,直接在 function 内的 this 上添加方法。

function Tab(nav, content) {
  this.nav = nav
  this.content = content
  this.getNav = function() {
    // ...
  }
  this.setNav = function() {
    // ...
  }
  this.add = function() {
    // ...
  }
}

这里 Tab 是语义, this.getNav/this.setNav/this.add 是语义,作为对象的方法。 另外,可以直接定义对象及其方法

var tab = {
  nav: '',
  content: '',
  getNav: function() {
    // ...
  },
  setNav: function() {
    // ...
  },
  add: function() {
    // ...
  }
}

tab.getNav/tab.setNav/tab.add 是语义,作为对象 tab 的方法。

语义3:作为独立的函数

/*
 * 判断对象是否是一个空对象
 * @param obj {Object}
 * @return {boolean}
 */
function isEmpty(obj) {
  for (var a in obj) {
    return false
  }
  return true
}
// 定义一个模块
~function() {
  // 辅助函数
  function now() {
    return (new Date).getTime()
  }
  // 模块逻辑...
}();
// 采用CommonJS规范的方式定义一个模块
define(require, exports, moduel) {
  // 辅助函数
  function now() {
    return (new Date).getTime()
  }
  // 模块逻辑...
})

isEmpty 作为一个全局函数存在,模块定义里面的 now 则作为局部函数存在,无论 isEmpty 还是 now 这里的 function 都指函数,它不依赖与对象和类,可以独立被调用。

语义4:匿名函数定义模块

// 全局命名空间
var RUI = {}
// ajax.js
~function(R) {
  // 辅助函数...
  ajax = {
    request: function() {
      // ...
    }
    getJSON: function() {
      // ...
    }
    ...
  }
  // 暴露出模块给 R
  R.ajax = ajax
}(RUI);
// event.js
~function(R) {
  // 辅助函数...
  // 事件模块定义...
  // 暴露出模块给 R
  R.event = event
}(RUI);
// dom.js
~function(R) {
  // 辅助函数...
  // DON模块定义...
  // 暴露出模块给 R
  R.dom = dom
}(RUI);

这里的匿名函数执行后把API对象暴露给了RUI,无论匿名函数内干了多少活,对应匿名函数外是看不到的,也是没有必要去理会的。最终关心的是公开的 API 方法,只要了解这些方法的参数及意义就可以马上使用它了。

语义5:匿名函数处理某些特殊效果如处理一些数据又不想暴露过多的变量

// 判断IE版本的hack方式
var IEVersion = function() {
  var undef, v = 
  var div = document.createElement('div')
  var all = div.getElementsByTagName('i')
  while (
    div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
    all[]
  );
  return v > ? v : undef
}();

最终只要一个结果 IEVersion,匿名函数内部用到了一些局部变量全部可以隔离开。这种方式对于一些临时性的数据加工非常有效,紧凑。

总结:

JavaScript 是 Eich 花  天的时间设计出来的,本是一个短小紧凑的脚本/函数式语言,因为市场营销的原因,为了迎合 Java,加入了一些类 Java 的面向对象特性(constructor, this, new)。 this,new 照搬过来, class 的功能却交给了 function 来承担。导致 JavaScript function 让人迷惑,一会用来定义类,一会又作为方法或函数。另外一部分人还挖掘出它可以用来定义模块等等。

这一切随着 ES 的到来结束了,ES 中的保留字 “class” 终于被实现了,定义类一律推荐使用 class。另外还有 extend 关键字,基本把 “类式继承” 都搞过来了。 Douglas 在 Nordic.js  大会上点评到 ES 最糟糕的设计之一就是 class,另外也不建议使用 this 和 new,这表明他依然赞成使用函数式语言方式去写 JavaScript,而不是基于类的面向对象式。

以上内容是我个人对JavaScript中function的多重理解,有不同理解的朋友,欢迎分享,共同学习进步。

Javascript 相关文章推荐
DOM 中的事件处理介绍
Jan 18 Javascript
js字符串日期yyyy-MM-dd转化为date示例代码
Mar 06 Javascript
JavaScript中的this关键字使用方法总结
Mar 13 Javascript
JavaScript中创建字典对象(dictionary)实例
Mar 31 Javascript
json数据处理及数据绑定
Jan 25 Javascript
JavaScript基础之流程控制语句的用法
Aug 31 Javascript
用vue2.0实现点击选中active其他选项互斥的效果
Apr 12 Javascript
微信小程序自定义底部弹出框
Nov 16 Javascript
Vue中控制v-for循环次数的实现方法
Sep 26 Javascript
javascript解析json格式的数据方法详解
Aug 07 Javascript
vue路由的配置和页面切换详解
Sep 09 Javascript
利用vue3+ts实现管理后台(增删改查)
Oct 30 Javascript
jquery衣服颜色选取插件效果代码分享
Aug 28 #Javascript
jQuery表单验证功能实例
Aug 28 #Javascript
jquery实现带缩略图的可定制高度画廊效果(5种)
Aug 28 #Javascript
通过XMLHttpRequest和jQuery实现ajax的几种方式
Aug 28 #Javascript
jQuery实现平滑滚动的标签分栏切换效果
Aug 28 #Javascript
jquery图片滚动放大代码分享(2)
Aug 28 #Javascript
浅谈JavaScript中的string拥有方法的原因
Aug 28 #Javascript
You might like
第五节--克隆
2006/11/16 PHP
php 静态变量的初始化
2009/11/15 PHP
zf框架的校验器InArray使用示例
2014/03/13 PHP
CodeIgniter中实现泛域名解析
2014/07/19 PHP
PHP静态成员变量
2017/02/14 PHP
php实现微信扫码支付
2017/03/26 PHP
PHP通过文件保存和更新信息的方法分析
2019/09/12 PHP
Javascript Select操作大集合
2009/05/26 Javascript
动态表格Table类的实现
2009/08/26 Javascript
javascript实现删除前弹出确认框
2015/06/04 Javascript
JavaScript+CSS实现的可折叠二级菜单实例
2016/02/29 Javascript
javascript实现简单计算器效果【推荐】
2016/04/19 Javascript
AngularJS实现动态编译添加到dom中的方法
2016/11/04 Javascript
React中使用collections时key的重要性详解
2017/08/07 Javascript
cropper js基于vue的图片裁剪上传功能的实现代码
2018/03/01 Javascript
JavaScript实现正则去除a标签并保留内容的方法【测试可用】
2018/07/18 Javascript
vue完成项目后,打包成静态文件的方法
2018/09/03 Javascript
Node.js 的 GC 机制详解
2019/06/03 Javascript
js实现旋转的星空效果
2019/11/01 Javascript
[01:59]DOTA2首部纪录片《Free to play》预告片
2014/03/12 DOTA
python局域网ip扫描示例分享
2014/04/03 Python
python线程、进程和协程详解
2016/07/19 Python
详谈python3中用for循环删除列表中元素的坑
2018/04/19 Python
Python输出指定字符串的方法
2020/02/06 Python
jupyter notebook运行命令显示[*](解决办法)
2020/05/18 Python
python文件操作seek()偏移量,读取指正到指定位置操作
2020/07/05 Python
详解基于Scrapy的IP代理池搭建
2020/09/29 Python
python+excel接口自动化获取token并作为请求参数进行传参操作
2020/11/10 Python
白俄罗斯在线大型超市:e-dostavka.by
2019/07/25 全球购物
ShellScript面试题一则-ShellScript编程
2014/06/24 面试题
毕业生找工作求职信
2014/08/05 职场文书
校长创先争优承诺书
2014/08/30 职场文书
开幕式邀请函
2015/01/31 职场文书
导游词之黄帝陵景区
2019/09/16 职场文书
JavaScript最完整的深浅拷贝实现方式详解
2022/02/28 Javascript
redis sentinel监控高可用集群实现的配置步骤
2022/04/01 Redis