面向对象的Javascript之一(初识Javascript)


Posted in Javascript onJanuary 20, 2012

1. Javascript最大的特性在于其灵活性。作为一名前端开发人员,既可以采用函数式的编程风格,也可以采用更复杂一点的面向对象的编程风格。不管你采用哪种风格,都可以完成一些非常有用的任务。因而,Javascript是一门面向过程的语言,同时也是一门面向对象的语言,进而可以模仿面向对象语言的编程模式和惯用法。我们用一个例子来说明:启动和停止动画。

如果你习惯于函数式的编程风格,代码会如下:

function startAnimation() { 
//启用动画 
} 
function stopAnimation() { 
//停止动画 
}

这种方法很简单,但却无法创建保存状态以及仅对内部状态进行操作的动画对象。下面我们定义一个类:
var Animation = function() { 
//动画类 
}; 
Animation.prototype.start = function() { 
//启用动画 
}; 
Animation.prototype.stop = function() { 
//停止动画 
}; 
/*用法如下*/ 
var anim = new Animation(); 
anim.start(); 
anim.stop();

如果你想将类的定义封装到一条声明中,则代码如下:
var Animation = function() { 
//动画类 
}; 
Animation.prototype = { 
start: function(){ 
//启用动画 
}, 
stop: function(){ 
//停止动画 
} 
};

这样让面向对象的程序员看起来更加眼熟,我们可以试着尝试更复杂一点的写法:
Function.prototype.method = function(name, fn){ 
this.prototype[name] = fn; 
} 
var Animation = function() { 
//动画类 
}; 
Animation.method("start", function(){ 
//启用动画 
}); 
Animation.method("stop", function(){ 
//停止动画 
});

我们为Function类扩展了一个方法method用于添加新方法。name代表函数名称,fn代表函数的具体实现。在基于此写法的基础之上,我们可以让函数支持链式调用:
Function.prototype.method = function(name, fn){ 
this.prototype[name] = fn; 
return this; 
} 
var Animation = function() { 
//动画类 
}; 
Animation.method("start", function(){ 
//启用动画 
}).method("stop", function(){ 
//停止动画 
});

至此已经见识了5种不同的编程风格,具有不同的代码量、编码效率和执行性能。你可以选择最适合当前项目的编程风格来进行工作。

2. Javascript是一门弱类型语言。声明变量时不必指定类型,但并不代表没有类型。Javascript包含三种基本类型:布尔型、数值型和字符串类型,此外还包含对象类型和函数类型,最后还包含空类型和未定义类型。基本类型按值传递,其他类型按引用传递。可以根据变量赋值改变类型,基本类型之间可以相互转换。toString()可以把数值或布尔值转化为字符串,parseInt()和parseFloat()可以将字符串转化为数值,双"非"操作可以将字符串或数值转化为布尔值。

3. Javascript函数是"一等"对象。函数可以存储在变量中,可作为参数传到其他函数,可作为返回值从其他函数中传出,也可在运行时构造。在于函数打交道时,带来了极大的灵活性和极强的表达能力,这些都是构建面向对象的基础。可以通过function() {...}创建匿名函数(没有函数名,也可赋给变量)。下面以例子来说明:

(function(){ 
var a = 10; 
var b = 5; 
alert(a * b);//返回50 
})();//函数定义就立即执行

之所以能立即执行,是因为函数声明后的一对括号。但我们发现,括号内空无一物,也并非完全如此。
(function(a, b){ 
alert(a * b);//返回50 
})(10, 5);//与前面等价

这个匿名函数与前一个等价,只是变量没有在函数内声明,而是直接从外部传入而已。其实,这个匿名函数也可以有个返回值,并赋给某个变量。
var c = (function(a, b){ 
return a * b;//返回50 
})(10, 5);//与前面等价 
alert(c);//50

匿名函数的最大用途是创建闭包。所谓闭包,就是一个受保护的变量空间,由内嵌函数生成。由于Javascript具有函数级的作用域,即定义在函数内部的变量在函数外部是不能被访问的,函数仅运行在定义它的作用域中,而不是在调用的作用域中。这样,就可以把变量包裹在匿名函数中加以保护。例如,你可以通过以下方式创建私有变量:
var c; 
(function(){ 
var a = 10; 
var b = 5; 
c = function(){ 
return a * b;//返回50 
} 
})(); 
c();//c可以访问a,b,即使它在匿名函数的外部也能被执行

4. Javascript对象是"易变"的。一切都是对象(除了3种基本类型),而且所有对象都是易变的。这意味着你能使用一些别的语言不存在的技术。例如为函数动态添加属性。
function displayError(error){ 
displayError.numTimesExecuted++; 
alert(error); 
} 
displayError.numTimesExecuted = 0;//意味着可对预先定义的类和对象进行修改

可以利用prototype机制在类的实例创建后再动态添加,此时对已定义的对象仍然有效。例如:
function Person(name, age) { 
this.name = name; 
this.age = age; 
} 
Person.prototype = { 
getName: function() { 
return this.name; 
}, 
getAge: function() { 
return this.age; 
} 
}; 
//先定义两个变量 
var miracle = new Person("Miracle", 28); 
var mike = new Person("Mike", 32); 
//动态添加一个方法 
Person.prototype.getGreeting = function() { 
return "Hello " + this.getName() + "!"; 
}; 
//displayGreeting()仅对Miracle有效 
miracle.displayGreeting = function() { 
alert(this.getGreeting()); 
}

与对象的易变性相关的就是反射(也可称为"内省"),即在运行时检查对象的属性和方法,并利用这些信息来实例化类和执行方法,甚至在开发时不需要知道它们的名称。借助于对象的这两大特性,可以完全模仿面向对象语言的高级特性,但要记住在Javascript中任何对象都是可以在运行时修改。

5. Javascript具有实现"继承"的天份。这里简单提及一下:Javascript继承包含"类式"继承和基于对象的原型式继承,这个话题我会在下一期的文章中详细论述。

最后总结一下,之所以采用面向对象和设计模式的思想来处理Javascript这种看似过程式的语言,到底有什么好处呢?我总结了以下几点供大家参考:

(1).可维护性。有助于降低模块之间的耦合性,对项目中代码可按模块和功能职责来划分。

(2).便于交流。对于一个大型团队来说,可能用设计模式很简单的术语可以高度概括你所负责实现的功能模块,而不必太多让团队其他成员关注过多的细节。

(3).提升性能。利用模式可以减少传送到客户端代码量的同时并提高程序运行的速度。

当然,有利就有弊。弊端在于:

(1).复杂度相对较高。获取可维护性的代价是以代码的高度重构和模块化的划分而成,对于一些新手来说,很难一下适应。

(2).部分模式反而降低性能。但是这种拖累依赖于你的项目需求,可能有时微不足道,有时难以接受。

因此,建议大家学会理解设计模式的应用场景,用对场景才是对设计模式的真正意义上的应用。盲目应用和用错场景就是误用,还不如不用。

Javascript 相关文章推荐
jQuery的显示和隐藏方法与css隐藏的样式对比
Oct 18 Javascript
jQuery中Ajax的get、post等方法详解
Jan 20 Javascript
JavaScript使用Math.Min返回两个数中较小数的方法
Apr 06 Javascript
javascript引用类型指针的工作方式
Apr 13 Javascript
javascript 闭包详解
Jul 02 Javascript
JavaScript运行过程中的“预编译阶段”和“执行阶段”
Dec 16 Javascript
理解javascript中的严格模式
Feb 01 Javascript
有关JS中的0,null,undefined,[],{},'''''''',false之间的关系
Feb 14 Javascript
推荐三款日期选择插件(My97DatePicker、jquery.datepicker、Mobiscroll)
Apr 21 jQuery
HTML5实现微信拍摄上传照片功能
Apr 21 Javascript
angular.js指令中transclude选项及ng-transclude指令详解
May 24 Javascript
React服务端渲染原理解析与实践
Mar 04 Javascript
MooBox 基于Mootools的对话框插件
Jan 20 #Javascript
formStorage 基于jquery的一个插件(存储表单中元素的状态到本地)
Jan 20 #Javascript
json的前台操作和后台操作实现代码
Jan 20 #Javascript
Prototype源码浅析 Enumerable部分(二)
Jan 18 #Javascript
JS中的public和private对象,即static修饰符
Jan 18 #Javascript
DOM 中的事件处理介绍
Jan 18 #Javascript
深入理解JavaScript系列(13) This? Yes,this!
Jan 18 #Javascript
You might like
PHP 木马攻击防御技巧
2009/06/13 PHP
PHP 开源AJAX框架14种
2009/08/24 PHP
ThinkPHP模板判断输出Defined标签用法详解
2014/06/30 PHP
PHP+iFrame实现页面无需刷新的异步文件上传
2014/09/16 PHP
PHP分享图片的生成方法
2018/04/25 PHP
javascript 定义新对象方法
2010/02/20 Javascript
jqTransform form表单美化插件使用方法
2012/07/05 Javascript
jquery中的查找parents与closest方法之间的区别
2013/12/02 Javascript
js中replace的用法总结
2013/12/27 Javascript
自制的文件上传JS控件可支持IE、chrome、firefox etc
2014/04/18 Javascript
jquery数组过滤筛选方法grep()简介
2014/06/06 Javascript
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
2016/06/12 Javascript
基于AngularJS实现iOS8自带的计算器
2016/09/12 Javascript
微信小程序 教程之注册程序
2016/10/17 Javascript
JS实现动画兼容性的transition和transform实例分析
2016/12/13 Javascript
微信小程序自定义头部导航栏(组件化)
2019/11/15 Javascript
javascript使用正则表达式实现注册登入校验
2020/09/23 Javascript
js实现纯前端压缩图片
2020/11/16 Javascript
[57:41]Secret vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python学习笔记之常用函数及说明
2014/05/23 Python
python实现kNN算法
2017/12/20 Python
python实现数据分析与建模
2019/07/11 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
2019/10/11 Python
基于python实现音乐播放器代码实例
2020/07/01 Python
python+playwright微软自动化工具的使用
2021/02/02 Python
HTML5 Canvas API中drawImage()方法的使用实例
2016/03/25 HTML / CSS
StubHub美国:购买或出售您的门票
2019/07/09 全球购物
Lucene推荐的分页方式是什么?
2015/12/07 面试题
银行自荐信范文
2013/10/07 职场文书
文明礼仪小标兵事迹
2014/01/12 职场文书
学校个人对照检查材料
2014/08/26 职场文书
争先创优活动总结
2014/08/27 职场文书
安全知识竞赛主持词
2015/06/30 职场文书
MySQL 时间类型的选择
2021/06/05 MySQL
Win11 S Mode版本泄露 正式上线后叫做Windows 11 SE
2021/11/21 数码科技