面向对象的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静态的url如何传递
May 03 Javascript
[原创]js获取数组任意个不重复的随机数组元素
Mar 15 Javascript
使用jQuery+HttpHandler+xml模拟一个三级联动的例子
Aug 09 Javascript
用JQUERY增删元素的代码
Feb 14 Javascript
node.js入门实例helloworld详解
Dec 23 Javascript
javascript对象的创建和访问
Mar 08 Javascript
Web程序员必备的7个JavaScript函数
Jun 14 Javascript
简单实现轮播图效果的实例
Jul 15 Javascript
微信小程序 蓝牙的实现实例代码
Jun 27 Javascript
Vue项目中引入外部文件的方法(css、js、less)
Jul 24 Javascript
React+Redux实现简单的待办事项列表ToDoList
Sep 29 Javascript
解决vue项目运行npm run serve报错的问题
Oct 26 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 split()函数的用法详解
2013/06/05 PHP
简单的php新闻发布系统教程
2014/05/09 PHP
详谈PHP程序Laravel 5框架的优化技巧
2016/07/18 PHP
thinkphp5 migrate数据库迁移工具
2018/02/20 PHP
判断页面是关闭还是刷新的js代码
2007/01/28 Javascript
javascript addBookmark 加入收藏 多浏览器兼容
2009/08/15 Javascript
toString()一个会自动调用的方法
2010/02/08 Javascript
返回页面顶部top按钮通过锚点实现(自写)
2013/08/30 Javascript
js中判断对象是否为空的三种实现方法
2013/12/23 Javascript
Javascript 中创建自定义对象的方法汇总
2014/12/04 Javascript
常用DOM整理
2015/06/16 Javascript
jQuery实现的网页右下角tab样式在线客服效果代码
2015/10/23 Javascript
jQuery监听浏览器窗口大小的变化实例
2017/02/07 Javascript
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
2017/03/25 Javascript
微信小程序商城项目之商品属性分类(4)
2017/04/17 Javascript
在Debian(Raspberry Pi)树莓派上安装NodeJS的教程详解
2017/09/19 NodeJs
JavaScript中常见内置函数用法示例
2018/05/14 Javascript
JavaScript两种计时器的实例讲解
2019/01/31 Javascript
vue实现密码显示与隐藏按钮的自定义组件功能
2019/04/23 Javascript
微信小程序用户授权、位置授权及获取微信绑定手机号
2019/07/18 Javascript
Windows8下安装Python的BeautifulSoup
2015/01/22 Python
使用Python的Twisted框架实现一个简单的服务器
2015/04/16 Python
Python中使用Counter进行字典创建以及key数量统计的方法
2018/07/06 Python
python 去除txt文本中的空格、数字、特定字母等方法
2018/07/24 Python
浅谈Python的list中的选取范围
2018/11/12 Python
python 根据时间来生成唯一的字符串方法
2019/01/14 Python
用python一行代码得到数组中某个元素的个数方法
2019/01/28 Python
python3对拉勾数据进行可视化分析的方法详解
2019/04/03 Python
利用python开发app实战的方法
2019/07/09 Python
python web框架中实现原生分页
2019/09/08 Python
《灯光》教学反思
2014/02/08 职场文书
项目建议书范文
2014/05/12 职场文书
毕业生自荐求职信书写的技巧
2019/08/26 职场文书
《蓝鲸的眼睛》读后感5篇
2020/01/15 职场文书
Android Flutter实现3D动画效果示例详解
2022/04/07 Java/Android
Python各协议下socket黏包问题原理
2022/04/12 Python