谈谈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 相关文章推荐
使用jQuery实现input数值增量和减量的方法
Jan 24 Javascript
JavaScript 面向对象与原型
Apr 10 Javascript
函数window.open实现关闭所有的子窗口
Aug 03 Javascript
jQuery实现高亮显示网页关键词的方法
Aug 07 Javascript
js鼠标点击图片切换效果代码分享
Aug 26 Javascript
浅谈jQuery绑定事件会叠加的解决方法和心得总结
Oct 26 Javascript
基于Javascript倒计时效果
Dec 22 Javascript
jQuery倒计时代码(超简单)
Feb 27 Javascript
移动端触摸滑动插件swiper使用方法详解
Aug 11 Javascript
js正则匹配多个全部数据问题
Dec 20 Javascript
解决vue init webpack 下载依赖卡住不动的问题
Nov 09 Javascript
Vue图片裁剪组件实例代码
Jul 02 Vue.js
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
DC《神奇女侠2》因疫情推迟上映 温子仁新恐怖片《恶性》撤档
2020/04/09 欧美动漫
Yii调试SQL的常用方法
2014/07/09 PHP
PHP的switch判断语句的“高级”用法详解
2014/10/01 PHP
PHP获取文件行数的方法
2015/06/10 PHP
php数据访问之增删改查操作
2016/05/09 PHP
php使用PDO执行SQL语句的方法分析
2017/02/16 PHP
php实现的生成迷宫与迷宫寻址算法完整实例
2017/11/06 PHP
在Z-Blog中运行代码[html][/html](纯JS版)
2007/03/25 Javascript
jQuery 定时局部刷新(setInterval)
2010/11/19 Javascript
jquery动画1.加载指示器
2012/08/24 Javascript
讨论html与javascript在浏览器中的加载顺序问题
2013/11/27 Javascript
浅谈EasyUI中Treegrid节点的删除
2015/03/01 Javascript
jQuery模拟360浏览器切屏效果幻灯片(附demo源码下载)
2016/01/29 Javascript
微信小程序(应用号)开发新闻客户端实例
2016/10/24 Javascript
JavaScript中字符串的常用操作方法及特殊字符
2018/03/18 Javascript
Nodejs 发布自己的npm包并制作成命令行工具的实例讲解
2018/05/15 NodeJs
JavaScript实现的前端AES加密解密功能【基于CryptoJS】
2018/08/28 Javascript
微信小程序webSocket的使用方法
2020/02/20 Javascript
微信小程序自定义modal弹窗组件的方法详解
2020/12/20 Javascript
Python中使用动态变量名的方法
2014/05/06 Python
python中的多线程实例教程
2014/08/27 Python
Python装饰器的函数式编程详解
2015/02/27 Python
Python使用Beautiful Soup包编写爬虫时的一些关键点
2016/01/20 Python
Php多进程实现代码
2018/05/07 Python
Django实战之用户认证(用户登录与注销)
2018/07/16 Python
python3 实现对图片进行局部切割的方法
2018/12/05 Python
python 服务器运行代码报错ModuleNotFoundError的解决办法
2020/09/16 Python
Python Pygame实现俄罗斯方块
2021/02/19 Python
阿里健康大药房:阿里自营网上药店
2017/08/01 全球购物
瑞士男士时尚网上商店:Babista
2020/05/14 全球购物
中职招生先进个人材料
2014/08/31 职场文书
精神文明建设汇报材料
2014/12/24 职场文书
上课说话检讨书
2015/01/27 职场文书
报案材料怎么写
2015/05/25 职场文书
opencv 分类白天与夜景视频的方法
2021/06/05 Python
蓝牙耳机怎么连接电脑win11? Win11蓝牙耳机连接电脑的技巧
2023/01/09 数码科技