面向对象的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 相关文章推荐
JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )
Feb 25 Javascript
JavaScript单元测试ABC
Apr 12 Javascript
JavaScript中判断对象类型的几种方法总结
Nov 11 Javascript
JavaScript淡入淡出渐变简单实例
Aug 06 Javascript
盘点javascript 正则表达式中 中括号的【坑】
Mar 16 Javascript
jQuery实现图片局部放大镜效果
Mar 17 Javascript
jQuery实现订单提交页发送短信功能前端处理方法
Jul 04 Javascript
js实现手机发送验证码功能
Mar 13 Javascript
利用jQuery实现简单的拖曳效果实例代码
Oct 20 jQuery
了解重排与重绘
May 29 Javascript
JS实现可控制的进度条
Mar 25 Javascript
微信小程序反编译的实现
Dec 10 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/11/20 PHP
php文件操作实例代码
2012/05/10 PHP
ThinkPHP实现批量删除数据的代码实例
2014/07/02 PHP
THINKPHP支持YAML配置文件的设置方法
2015/03/17 PHP
php数据库操作model类(使用__call方法)
2016/11/16 PHP
PHP 实现文件压缩解压操作的方法
2019/06/14 PHP
jQuery表单验证插件formValidator(改进版)
2012/02/03 Javascript
Jquery each方法跳出循环,并获取返回值(实例讲解)
2013/12/12 Javascript
在页面加载完成后通过jquery给多个span赋值
2014/05/21 Javascript
jQuery操作表单常用控件方法小结
2015/03/23 Javascript
jQuery中animate()的使用方法及解决$(”body“).animate({“scrollTop”:top})不被Firefox支持的问题
2017/04/04 jQuery
node.js平台下利用cookie实现记住密码登陆(Express+Ejs+Mysql)
2017/04/26 Javascript
NodeJS自定义模块写法(详解)
2017/06/27 NodeJs
jquery实现一个全局计时器(商城可用)
2017/06/30 jQuery
微信小程序之自定义组件的实现代码(附源码)
2018/08/02 Javascript
10个最受欢迎的 JavaScript框架(推荐)
2019/04/24 Javascript
Echarts动态加载多条折线图的实现代码
2019/05/24 Javascript
layer关闭当前窗口页面以及确认取消按钮的方法
2019/09/09 Javascript
js Math数学简单使用操作示例
2020/03/13 Javascript
Python中使用中文的方法
2011/02/19 Python
深入解析Python中的上下文管理器
2016/06/28 Python
DataFrame中去除指定列为空的行方法
2018/04/08 Python
50行Python代码获取高考志愿信息的实现方法
2019/07/23 Python
python通过移动端访问查看电脑界面
2020/01/06 Python
Python的控制结构之For、While、If循环问题
2020/06/30 Python
香港万宁官方海外旗舰店:香港健与美连锁店
2018/09/27 全球购物
电子专业推荐信范文
2013/11/18 职场文书
运动会开幕式邀请函
2014/01/22 职场文书
优秀本科生求职推荐信
2014/02/24 职场文书
感恩老师的演讲稿
2014/05/06 职场文书
党的群众路线教育实践活动总结报告
2014/07/03 职场文书
重阳节演讲稿:尊敬帮助老人 弘扬传统美德
2014/09/25 职场文书
2014法院四风问题对照检查材料思想汇报
2014/10/04 职场文书
岗位聘任协议书
2015/09/21 职场文书
2016年秋季开学典礼新闻稿
2015/11/25 职场文书
python 爬取华为应用市场评论
2021/05/29 Python