面向对象的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遭遇CoffeeScript的时候 使用分享
Sep 17 Javascript
js控制CSS样式属性语法对照表
Dec 11 Javascript
在JavaScript中操作时间之getUTCDate()方法的使用
Jun 10 Javascript
Node.js connect ECONNREFUSED错误解决办法
Sep 15 Javascript
基于Vue2实现的仿手机QQ单页面应用功能(接入聊天机器人 )
Mar 30 Javascript
提升node.js中使用redis的性能遇到的问题及解决方法
Oct 30 Javascript
js中this的指向问题归纳总结
Nov 28 Javascript
vue组件间的参数传递实例详解
Apr 26 Javascript
vue子路由跳转实现tab选项卡
Jul 24 Javascript
js时间转换毫秒的实例代码
Aug 21 Javascript
微信小程序 自定义复选框实现代码实例
Sep 04 Javascript
Angular封装表单控件及思想总结
Dec 11 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
E路文章系统PHP
2006/12/11 PHP
PHP实现的AES加密、解密封装类与用法示例
2018/08/02 PHP
PHP生成随机字符串实例代码(字母+数字)
2019/09/11 PHP
不用ajax实现点击文字即可编辑的方法
2007/12/16 Javascript
js removeChild 障眼法 可能出现的错误
2009/10/06 Javascript
JavaScript 模式之工厂模式(Factory)应用介绍
2012/11/15 Javascript
javascript 使td内容不换行不撑开
2012/11/29 Javascript
jquery cookie实现的简单换肤功能适合小网站
2013/08/25 Javascript
AJAX跨域请求json数据的实现方法
2013/11/11 Javascript
JS根据变量保存方法名并执行方法示例
2014/04/04 Javascript
jQuery实现可编辑的表格实例讲解(2)
2015/09/17 Javascript
vue.js表格组件开发的实例详解
2016/10/12 Javascript
vue和iview实现Scroll 数据无限滚动功能
2019/10/31 Javascript
微信小程序 scroll-view 实现锚点跳转功能
2019/12/12 Javascript
Vue组件间的通信pubsub-js实现步骤解析
2020/03/11 Javascript
[52:03]Secret vs VG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
PyQt5每天必学之进度条效果
2018/04/19 Python
无法使用pip命令安装python第三方库的原因及解决方法
2018/06/12 Python
python实现自主查询实时天气
2018/06/22 Python
python定向爬虫校园论坛帖子信息
2018/07/23 Python
python分批定量读取文件内容,输出到不同文件中的方法
2018/12/08 Python
Python函数参数匹配模型通用规则keyword-only参数详解
2019/06/10 Python
python+adb命令实现自动刷视频脚本案例
2020/04/23 Python
HTML5 MiranaVideo播放器 (代码开源)
2010/06/11 HTML / CSS
Bootstrap File Input文件上传组件
2020/12/01 HTML / CSS
DJI大疆无人机官方商城:全球领先的无人飞行器研发和生产商
2016/12/21 全球购物
美国男士内衣品牌:Tommy John
2017/12/22 全球购物
印度领先的眼镜电子商务网站:Lenskart
2019/12/16 全球购物
CK澳大利亚官网:Calvin Klein澳大利亚
2020/12/12 全球购物
Ibatis的核心配置文件都有什么
2014/09/08 面试题
护理专业学生的求职信范文
2013/12/11 职场文书
劲霸男装广告词改编版
2014/03/21 职场文书
心理咨询承诺书
2014/05/20 职场文书
机械工程及其自动化专业求职信
2014/08/08 职场文书
户籍证明书标准模板
2014/09/10 职场文书
2016党员入党决心书
2015/09/22 职场文书