【总结】富有表现力的JavaScript
JavaScript的灵活性
JavaScript是目前最流行、应用最广泛的语言之一,它是一种极富表现力的语言,它具有C家族语言所罕见的特性。这种语言允许我们使用各种方式来完成同一个任务或者功能,还允许我们在面向对象编程的过程使用函数式编程中的概念来丰富其实现方式。这种语言允许我们采用多种不同的编程风格进行编程,如简单一些的函数式编程,复杂一些的面向对象编程。所以我们可以在长期的编码过程中,培养专门属于自己的编程风格,下面的例子会体现出JavaScript的灵活性。
下面我们将要实现一个模拟开始播放音乐和停止播放音乐的小功能,代码如下:
/************************************************/
//方法一:传统的函数式编码方式
function start() {
console.log("music start");
} function stop() {
console.log("music stop");
} //页面调用方法一
start();
stop();
/************************************************/
//方法二:利用prototype
var Player=function() {} //声明function对象 Player.prototype.start=function(){ //为对象的prototype添加方法
console.log("music start by prototype");
}
Player.prototype.stop=function(){
console.log("music stop by prototype");
} //页面调用方法二
Player =new Player();
Player.start();
Player.stop();
/************************************************/
//方法三:prototype进一步封装
var ControlPlayer=function(){} ControlPlayer.prototype={
start:function () {
console.log("music start prototype-start");
},
stop:function(){
console.log("music stop prototype-stop");
}
} //页面调用方法三
var c=new ControlPlayer();
c.start();
c.stop();
/************************************************/
//方法四:通过prototype添加方法,链式调用
Function.prototype.method=function(name,fn){ //注意function的大小写,小写会不识别句点
this.prototype[name]=fn;
return this;//链式调用
} ControlPlayer.method('start',function(){
console.log('music starting by chain... ...');
}).method('stop',function(){
console.log('music stopping by chain... ...');
}); //页面调用方法四
ControlPlayer.prototype.start();
ControlPlayer.prototype.stop(); /************************************************/
//方法五:通过prototype添加方法,非链式调用
Function.prototype.method=function(name,fn){ //注意function的大小写,小写会不识别句点
this.prototype[name]=fn;
//return this;//链式调用
} ControlPlayer.method('start',function(){
console.log('music starting... ...');
}); ControlPlayer.method('stop',function(){
console.log('music stopping... ...');
}); //页面调用方法五,同四
ControlPlayer.prototype.start();
ControlPlayer.prototype.stop();
方法一很简单,但是无法创建可以保存状态并且具有一些仅仅对其内部状态进行操作的方法的对象;方法二中将两个方法(start、stop)赋给该类的prototype属性;如果希望把类的定义封装在一起,可以采用方法三的做法;方法四中使用Function.prototype.method为该类添加新的方法,它有两个参数,第一个是字符串型的方法名称,第二个是具体的好函数;如果对方法四进行扩展,可以让它返回this,这样就可以进行链式调用,也就是方法五的内容。通过以上的几个例子可以发现,不使用prototype属性定义的对象方法,是静态的,只能用类名进行调用,另外此静态方法中无法使用this关键字来调用对象的其他属性;而使用prototype属性定义的对象方法,是非静态的,只有在实例化之后才能调用,其方法内部可以使用this关键字来调用对象的其他属性;只有function才能被实例化,而Object则不能被实例化,前者可以通过new操作符,而后者可以通过赋值把对象保存在变量中并通过该变量对其内部成员进行访问;如果是对象中的function,需要new一下这个function再使用。
弱类型语言
在Javascript中,声明变量时可以不指定类型,但是这不意味着变量没有类型,变量的类型取决于变量的值。在Javascript中有5中原始类型,分别是Number、String、Boolean、Undefined和Null,此外还有对象类型Object和包含可执行代码的函数类型,前者是一种复合数据类型(数组也是Object类型,它包含着一批有序的值集合)。原始类型按值传递,而其他类型包括复合对象是按引用传递。Javascript中,可以通过赋值来改变数据类型,原始数据类型之间也可以进行转换,toString方法可以把Number和Boolean类型转成字符串,parseFloat和parseInt可以把字符变为数值型,双重非操作可以把Number和String转成Boolean类型。弱类型的变量带来了极大的灵活性,Javascript会根据值进行自动转换。
函数是一等对象
在Javascript中,函数可以存储在变量中,可以作为参数传给其他函数,可以作为返回值从其他函数传出,还可以在运行时进行构造,这些特性带来了极大的灵活性和极强的表达能力,而这些正是构建传统面向对象的框架基础。下面的代码创建了一个匿名函数并赋值给一个变量,代码如下:
(function(){
console.log('anonymous function!');
})(); //此处括号表示立即调用,另外如果没有分号,多个匿名函数时会报错 (function(){
var a=20;
var b=10;
console.log(a*b);
})(); (function(a,b){
console.log(a*b);
})(12,13);//括号中传入的参数和function中的形参一致,参数由外部传入 var result =(function(a,b){
return a*b;
})(3,3);
console.log(result);//result的值是匿名函数的返回值
匿名函数最有趣的用途是用于创建闭包(closure),闭包是一个受到保护的变量空间,由内嵌函数生成。Javascript具有函数级的作用域,这意味着在函数内部定义的变量在函数的外部是不可以访问的。Javascript的作用域是词法性质,这意味着函数是运行在定义它的作用域中,而不是调用它的作用域中。把这两个因素结合起来,就可以通过把变量包裹在匿名函数中而对其加以保护,代码如下:
var item;
(function(){
var a=12;
var b=23;
item=function(){
return a*b;
};
})(); item();
变量a和b定义在匿名函数中,因为函数item定义在这个闭包中,所以它能访问这两个变量,即使是在该闭包结束后。
对象的易变性
在JavaScript中,一切都是对象,除了那几种基本类型,即便是基本类型,在必要的时候也会被自动包装为对象,所有对象都是易变的(mutable),这意味着可以在JavaScript中使用其他语言不允许的技术。例如,为函数添加属性:
function displayError(msg) {
displayError.numTimesExcuted++;//新增属性
alert(msg);
} displayError.numTimesExcuted=0;
这意味着可以对先前的类或实例化的对象进行修改,代码如下:
//定义Person类
function Person(name,age){
this.name=name;
this.age=age;
}
//为Person类添加GetName和GetAge方法
Person.prototype={
GetName:function(){
return this.name;
},
GetAge:function(){
return this.age;
}
}
//新建一个Person类的实例tom
var tom=new Person('tom',21);
var name=tom.GetName();
console.log(name); //为Person类添加Greeting方法
Person.prototype.Greeting=function(){
return 'hi,'+this.GetName();
}
//新建一个Person类的实例lucy
var lucy=new Person('lucy',23);
console.log(lucy.Greeting());
//为tom实例添加displayGreeting方法
tom.displayGreeting=function(){
alert(this.Greeting());
}
tom.displayGreeting();
在这个例子中,Greeting方法是在创建Person类的两个实例(tom、lucy)之后添加的,但是这两个实例依然能够访问到,这是因为prototype的工作机制。对象tom还得到了displayGreeting方法,这是其他实例所没有的。与对象的易变性相关的还有一个内省(introspection)的概念,在运行时检查对象所具有的属性和方法,还可以使用这种方法动态地创建类和执行其方法,这种技术称之为反射(reflection),大多数模仿传统面向对象的特性的技术都是基于对象的易变性和反射。在JavaScript中,任何东西都可以在运行时动态地改变,当然也有不利的一面,因为我们定义一个具有一套方法的类,到最后却不能把保证它依旧完好如初。
JavaScript的继承
JavaScript中的继承并非传统的面向对象的真正的继承,而是基于prototype原型链的继承方式,它可以用来模拟传统的基于类的继承方式,但是性能略有差异,具体的使用还要看需求。
JavaScript中的设计模式
JavaScript的强大的表现力赋予了我们在运用设计模式编写代码时极大的创造性,在JavaScript中使用设计模式主要有以下几个原因:
<1>可维护性:有助于降低模块间的耦合性,使代码重构和换用不同的模块变得容易,使得代码维护更加容易;
<2>沟通方便:设计模式为处理不同类型的对象提供了一套通用的术语,这样编码人员在沟通时只要讲明采用的设计模式即可清晰地表达,而不必涉足更细节层次的东西;
<3>提升性能:某些设计模式会大幅提升应用的性能,减少网络传输,比如享元模式和代理模式,当然也有好多设计模式会降低性能,这个就需要使用者自行把握。
总结
JavaScript的丰富表现力是其力量之源,即使这种弱类型语言没有自己的内置对象,但是我们可以随时根据自己的需求进行扩展,由于其实弱类型语言,所以定义变量时并不需要指定类型。函数是一等对象,并且可以动态创建,因此可以创建闭包;所有的对象都是易变的,可以在运行时修改;可以使用的继承方式有两种,一种是原型链继承、另一种是类式继承,它们各有优缺点。JavaScript的设计模式并非完全有益,需要使用者根据具体的需求进行决策,使用不当甚至会产生负面的效果,过度复杂的架构会把应用程序拖入泥沼,所以要根据我们自己的编码风格选择适合的模式来完成具体的工作。
作者:悠扬的牧笛
博客地址:http://www.cnblogs.com/xhb-bky-blog/p/5866675.html
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
【总结】富有表现力的JavaScript的更多相关文章
- 一、富有表现力的JavaScript
第一章:富有表现力的JavaScript 1.1 JavaScript的灵活性 1.2 弱类型语言 1.3 函数是一等对象 1.4 对象的易变性 1.5 继承 1.6 JavaScript ...
- 富有表现力的javascript
1.javascript的灵活性,你可以把它写的很简单,也可以写的很复杂,简直就是随心所欲: 2.javascript是弱类型语言,定义变量的时候不用声明变量类型,不声明类型,并不是说,javascr ...
- 《JavaScript设计模式》笔记之第一、二章:富有表现力的JavaScript 和 接口
第一章 创建一个类 方法一: var Anim = function() { ... }; Anim.prototype.start = functi ...
- JS设计模式——1.富有表现力的JS
创建支持链式调用的类(构造函数+原型) Function.prototype.method = function(name, fn){ this.prototype[name] = fn; retur ...
- 8款极具表现力的jQuery/CSS3网页菜单
上一篇我向大家分享了7款效果震憾的HTML5应用组件,今天主要来分享一下CSS3网页菜单,因为在一个网站中,菜单起着举足轻重的作用,所以作为WEB开发人员,我们有必要将网站的菜单设计得尽量完美,下面向 ...
- 充满想象力的 JavaScript 物理和重力实验
在这个列表中挑选了9个物理和重力实验,用来展示 Javascript 的强大.几年前,所有这些实验都必须使用 Java 或 Flash 才能做.在下面这些惊人的例子中,就个人而言,我比较喜欢仿真布料的 ...
- 9个充满想象力的 JavaScript 物理和重力实验
在这个列表中挑选了9个物理和重力实验,用来展示 Javascript 的强大.几年前,所有这些实验都必须使用 Java 或 Flash 才能做.在下面这些惊人的例子中,就个人而言,我比较喜欢仿真布料的 ...
- 富有魅力的git stash
git stash 会把当前的改动暂时搁置起来, 也就是所谓的git 暂存区. 你可以执行 git stash list 来查看你所有暂存的东东. 也可以 git stash apple ** 来拿下 ...
- Stylus-富有表现力的、动态的、健壮的CSS
今天总结一下Stylus记一些常用的也是最基本的用法 一. 选择器 Stylus是基于缩进的这让我们可以更快捷的编写css比如 body { margin:; paddind:; font-size ...
随机推荐
- 使用jquery.qrcode生成二维码(转)
jQuery 的 qrcode 插件就可以在浏览器端生成二维码图片. 这个插件的使用非常简单: 1.首先在页面中加入jquery库文件和qrcode插件. <script type=" ...
- HTTP、HTTP2
HTTP.HTTP2.0.SPDY.HTTPS 你应该知道的一些事 原文链接:http://www.alloyteam.com/2016/07/httphttp2-0spdyhttps-readi ...
- unable to boot the simulator,无法启动模拟器已解决
突然模拟器报错:unable to boot the simulator(无法启动模拟器) 试了好几种解决办法,删除所有的模拟器重启以后再添加,删除钥匙串登陆中的证书,重新安装Xcode都不行 最后通 ...
- 记录一次Quartz2D学习(七)
(六)内主要讲述了图片的裁剪 本次主要讲交互 7.交互 7.1 通过外部刷新内部的显示效果 初始化的时候设定好初始值,调用setNeedsDisplay方法来重新绘制 - (instancetype ...
- Hadoop技巧(01):插件,终端权限
阅读目录 序 HDFS权限 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 序 在ha ...
- 今天搞了一天的CentOS,唉,实在感觉自己渺小啊
从别人处转载一篇文章:http://my.oschina.net/idiotsky/blog/303545 这个文章讲的很好,因为告诉了我怎么去查看ftp有关的SElinux的bool变量值以及设定. ...
- Ubuntu 下ibus拼音输入法启用 (ubuntu 16.04
Ubuntu 下ibus拼音输入法启用 我安装的是英文版的ubuntu 16.04,打开只带英文,并没有中文. 设置输入法为iBus 从system settings 进入language suppo ...
- ESLint规则配置说明
"no-alert": 0,//禁止使用alert confirm prompt "no-array-constructor": 2,//禁止使用数组构造器 & ...
- $.ajax()方法详解
jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(p ...
- [LeetCode] Paint House 粉刷房子
There are a row of n houses, each house can be painted with one of the three colors: red, blue or gr ...