谈谈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 相关文章推荐
浅说js变量
May 25 Javascript
js判断两个日期是否相等的方法
Sep 10 Javascript
JQuery实现倒计时按钮具体方法
Nov 14 Javascript
javascript设置金额样式转换保留两位小数示例代码
Dec 04 Javascript
JS执行删除前的判断代码
Feb 18 Javascript
JavaScript 深层克隆对象详解及实例
Nov 03 Javascript
JavaScript实现简单评论功能
Aug 17 Javascript
Vue组件之Tooltip的示例代码
Oct 18 Javascript
JavaScript实现简单的文本逐字打印效果示例
Apr 12 Javascript
默认浏览器设置及vue自动打开页面的方法
Sep 21 Javascript
深入探索VueJS Scoped CSS 实现原理
Sep 23 Javascript
Vue v-for中的 input 或 select的值发生改变时触发事件操作
Aug 31 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
MySQL数据库转移,access,sql server 转 MySQL 的图文教程
2007/09/02 PHP
ezSQL PHP数据库操作类库
2010/05/16 PHP
PHP file_get_contents函数读取远程数据超时的解决方法
2015/05/13 PHP
[原创]解决wincache不支持64位PHP5.5/5.6的问题(提供64位wincache下载)
2016/06/22 PHP
PHP使用mysqli同时执行多条sql查询语句的实例
2019/03/22 PHP
PHP+redis实现微博的推模型案例分析
2019/07/10 PHP
javascript 遍历验证所有文本框的值
2009/08/27 Javascript
javascript的onchange事件与jQuery的change()方法比较
2009/09/28 Javascript
jquery.cookie用法详细解析
2013/12/18 Javascript
JS获取url链接字符串 location.href
2013/12/23 Javascript
php析构函数的具体用法小结
2014/03/11 Javascript
javascript+css3 实现动态按钮菜单特效
2016/02/06 Javascript
微信小程序开发一键登录 获取session_key和openid实例
2016/11/23 Javascript
Bootstrap选项卡学习笔记分享
2017/02/13 Javascript
JavaScript实现简单的双色球(实例讲解)
2017/07/31 Javascript
详解angularjs popup-table 弹出框表格指令
2017/09/20 Javascript
shiro授权的实现原理
2017/09/21 Javascript
ES6下子组件调用父组件的方法(推荐)
2018/02/23 Javascript
redux中间件之redux-thunk的具体使用
2018/04/17 Javascript
详解vue axios二次封装
2018/07/22 Javascript
vuejs router history 配置到iis的方法
2018/09/20 Javascript
使用 vue 实例更好的监听事件及vue实例的方法
2019/04/22 Javascript
微信小程序中悬浮窗功能的实现代码
2019/08/02 Javascript
vue.js实现h5机器人聊天(测试版)
2020/07/16 Javascript
[01:02:26]DOTA2-DPC中国联赛 正赛 SAG vs RNG BO3 第二场 1月18日
2021/03/11 DOTA
使用python的pexpect模块,实现远程免密登录的示例
2019/02/14 Python
基于Pytorch版yolov5的滑块验证码破解思路详解
2021/02/25 Python
浅谈CSS3动画的回调处理
2016/07/21 HTML / CSS
HTML5 Canvas如何实现纹理填充与描边(Fill And Stroke)
2013/07/15 HTML / CSS
劳模事迹材料范文
2014/12/24 职场文书
员工评语范文
2014/12/31 职场文书
大班上学期个人总结
2015/02/13 职场文书
2016年世界艾滋病日宣传活动总结
2016/04/01 职场文书
未来,这5大方向都很适合创业
2019/07/22 职场文书
鲲鹏 CentOS 7 安装Python3.7
2022/05/11 Servers
clear 万能清除浮动(clearfix:after)
2023/05/21 HTML / CSS