面向对象的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 相关文章推荐
[原创]网络复制内容时常用的正则+editplus
Nov 30 Javascript
读取input:file的路径并显示本地图片的方法
Sep 23 Javascript
javascript如何写热点图
Dec 08 Javascript
jquery插件jquery.LightBox.js实现点击放大图片并左右点击切换效果(附demo源码下载)
Feb 25 Javascript
input框中的name和id的区别
Nov 16 Javascript
Javascript 数组去重的方法(四种)详解及实例代码
Nov 24 Javascript
Angualrjs 表单验证的两种方式(失去焦点验证和点击提交验证)
May 09 Javascript
vue监听scroll的坑的解决方法
Sep 07 Javascript
vuejs实现本地数据的筛选分页功能思路详解
Nov 15 Javascript
React中的refs的使用教程
Feb 13 Javascript
详解react-native WebView 返回处理(非回调方法可解决)
Feb 27 Javascript
JavaScript实现动态生成表格
Aug 02 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编程最快明白》第七讲:php图片验证码与缩略图
2010/11/01 PHP
php curl 伪造IP来源的实例代码
2012/11/01 PHP
php压缩和解压缩字符串的方法
2015/03/14 PHP
PHP 数据结构队列(SplQueue)和优先队列(SplPriorityQueue)简单使用实例
2015/05/12 PHP
php实现遍历文件夹的方法汇总
2017/03/02 PHP
php+js实现的拖动滑块验证码验证表单操作示例【附源码下载】
2020/05/27 PHP
PHP中的异常处理机制深入讲解
2020/11/10 PHP
js中的时间转换—毫秒转换成日期时间的示例代码
2014/01/26 Javascript
jquery禁止回车触发表单提交
2014/12/12 Javascript
jQuery团购倒计时特效实现方法
2015/05/07 Javascript
angularjs实现文字上下无缝滚动特效代码
2016/09/04 Javascript
nodejs连接mongodb数据库实现增删改查
2016/12/01 NodeJs
jquery实现文字单行横移或翻转(上下、左右跳转)
2017/01/08 Javascript
JS实现微信摇一摇原理解析
2017/07/22 Javascript
详解js跨域请求的两种方式,支持post请求
2018/05/05 Javascript
node和vue实现商城用户地址模块
2018/12/05 Javascript
elementUI select组件默认选中效果实现的方法
2019/03/25 Javascript
vue指令做滚动加载和监听等
2019/05/26 Javascript
开发中常用的25个JavaScript单行代码(小结)
2019/06/28 Javascript
vue用BMap百度地图实现即时搜索功能
2019/09/26 Javascript
vue data恢复初始化数据的实现方法
2019/10/31 Javascript
Python中异常重试的解决方案详解
2017/05/05 Python
Python基于回溯法子集树模板解决野人与传教士问题示例
2017/09/11 Python
Python简单生成随机数的方法示例
2018/03/31 Python
python随机生成大小写字母数字混合密码(仅20行代码)
2020/02/01 Python
Python MOCK SERVER moco模拟接口测试过程解析
2020/04/13 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
2020/06/11 Python
Yahoo-PHP面试题3
2012/01/14 面试题
办公室人员先进事迹
2014/01/27 职场文书
《草原的早晨》教学反思
2014/04/08 职场文书
《真想变成大大的荷叶》教学反思
2014/04/14 职场文书
健康教育主题班会
2015/08/14 职场文书
音乐课《小猫钓鱼》教学反思
2016/02/18 职场文书
python基于OpenCV模板匹配识别图片中的数字
2021/03/31 Python
详细谈谈JavaScript中循环之间的差异
2021/08/23 Javascript
Python通过loop.run_in_executor执行同步代码 同步变为异步
2022/04/11 Python