搜索
首页web前端js教程使用CoffeeScrip优美方式编写javascript代码_javascript技巧

JavaScript无疑是在web最伟大的发明之一,几乎一切网页动态效果都是基于它丰富的计算能力。而且它的能力在各种新的JavaScript的Engine下也越来越强了,比如Google Chrome用的V8 Engine。

但是由于诞生的太早,有很多语法定义在今天看来有些效率低下了,一些更加先进的语法形式,由于历史原因,没办法加入到现在的JavaScript语言中,可以说一种遗憾。

世界上的很多天才都在为构建更好的JavaScript而努力。已经有了很多尝试,其中最有前途的,无非就是CoffeeScript和TypeScript了。面对CoffeeScript,我有一见如故的感觉;而TypeScript也激发了我极大的兴趣。CoffeeScript和TypeScript一样,都是编译为JavaScript的语言,它们都增强了JavaScript的表达能力。这篇文章是讲CoffeeScript的,TypeScript将放在下一篇再讲。

所谓编译为JavaScript,是指CoffeeScript和TypeScript没有实现自己的运行时,它们都是编译为等价的JavaScript代码,然后放在JavaScript的解释器上运行。

CoffeeScript

简洁性

CoffeeScript给人最大的印象就是其简洁的表达。下面代码是我从CoffeeScript中文摘抄下来的:

# 赋值:
number  = 42
opposite = true
# 条件:
number = -42 if opposite
# 函数:
square = (x) -> x * x
# 数组:
list = [1, 2, 3, 4, 5]
# 对象:
math =
 root:  Math.sqrt
 square: square
 cube:  (x) -> x * square x
# Splats:
race = (winner, runners...) ->
 print winner, runners
# 存在性:
alert "I knew it!" if elvis?
# 数组 推导(comprehensions):
cubes = (math.cube num for num in list)

上面的代码会编译为等价的JavaScript代码:

var cubes, list, math, num, number, opposite, race, square,
 __slice = [].slice;
number = 42;
opposite = true;
if (opposite) {
 number = -42;
}
square = function(x) {
 return x * x;
};
list = [1, 2, 3, 4, 5];
math = {
 root: Math.sqrt,
 square: square,
 cube: function(x) {
  return x * square(x);
 }
};
race = function() {
 var runners, winner;
 winner = arguments[0], runners = 2 <= arguments.length &#63; __slice.call(arguments, 1) : [];
 return print(winner, runners);
};
if (typeof elvis !== "undefined" && elvis !== null) {
 alert("I knew it!");
}
cubes = (function() {
 var _i, _len, _results;
 _results = [];
 for (_i = 0, _len = list.length; _i < _len; _i++) {
  num = list[_i];
  _results.push(math.cube(num));
 }
 return _results;
})();
run: cubes

CoffeeScript力求简洁。其简洁性首先表现在对一些仅用于语法控制的符号进行了去除。这其中包括:

取消分号

取消var声明

取消大括号包围内层代码,使用缩进取代

函数调用在没有歧义的情况下可以省略括号

var声明涉及到复杂又很鸡肋的JavaScript变量作用域机制。这部分内容先放着不讲。CoffeeScript通过完全取消var声明机制而使得问题得到简化。总之,在CoffeeScript世界里,变量不用事先声明,直接用就是了。而且这种用法基本没有什么危险。

缩进在CoffeeScript中不仅仅在于美化代码,其代表了代码层次的组织,是有特别的含义的。简单地说就是,不适用大括号包围内层代码,而是内层代码要缩进。不同的缩进代表了不同的代码层次。形式和内容是一致的。

缩进的例子:

#if缩进
if true
 'true'
else
 'false'
#while缩进
while true
 'true'
#函数缩进
(n) ->
 n * n
#对象字面量缩进
kids =
 brother:
  name: "Max"
  age: 11
 sister:
  name: "Ida"
  age: 9 

在不引起歧义的情况下,CoffeeScript的函数调用可以省略括号。例如console.log(object)可以简化为console.log object。所谓引起歧义的一个例子就是无参数的情况下,console.log就不知道是取出函数型属性log还是调用函数log了。

CoffeeScript的函数表达式也做了极致的精简精简。一个单行函数的定义可以这样:

square = (x) -> x * x

而多行函数也是通过缩进来组织的。一个空的函数最为简洁,是这样:->。

函数的这种简洁表达使得传递回调函数非常便利。一个数组的map可能像这样就足够了:

list = [1, 2, 3]
list.map (e) -> e+1

而等效的JavaScript代码就不能这么马虎:

list = [1, 2, 3];
list.map(function(e) { return e + 1; });

增强的表达

CoffeeScript提供了JavaScript所没有的一些强大的表达语法,这也是被称为语法糖的东西。在我印象中,这种增强性是很多的,我举出两个有代表性的例子:

字符串插值法

列表解析

其中字符串插值法是对现有字符串能力的一种扩充和语法上的简化;而列表解析就要涉及到观念上的改变了。前者是一种改良,后者则是一种变革。

字符串插值法

在CoffeeScript的字符串里,可以用#{…}嵌入一个表达式。例如:

"#{ 22 / 7 } is a decent approximation of π"

等价于:

"" + (22 / 7) + " is a decent approximation of π";

插值在这里起到占位的作用,使得动态内容的字符串更容易构建。我想人人都能接受这样的表达。

列表解析

列表解析是CoffeeScript的世界里的重要一员。它改变了循环的思路。CoffeeScript没有提供像JavaScript那样的for循环结构,而是统统转化为列表解析。一个常规的JavaScript for循环,像下面这样:

food_list = ['toast', 'cheese', 'wine'];
for (i = 0, len = food_list.length; i < len; i++) {
 food = food_list[i];
 eat(food);
}

用CoffeeScript实现就是:

food_list = ['toast', 'cheese', 'wine']
eat food for food in food_list #做个小补充,for循环的单条语句的写法

单单是上面的例子不足以显示列表解析的强大(却看到它的简洁了)。在继续这个话题之前,我觉得我有必要补充一下另一个涉及到CoffeeScript理念的东西了:一切皆是表达式。

在CoffeeScript世界里,一切语句都是表达式语句,都会返回一个值。函数调用默认会返回最后一条语句的值。if条件结构也会返回值,其返回的是执行的最后一条语句的值。循环结构有些不同,其会将每次循环的结果都保存在一个数组里,作为此循环结构的值。例如下面代码的list结果就是[5, 4, 3, 2, 1]。

num = 6
list = while num -= 1
 num

回到列表解析的主题。与while一样,for结构也是一种循环的表达,其结果也是一个数组。回到先前的例子,下面的小代码的list结果就是['t', 'c', 'w']。

food_list = ['toast', 'cheese', 'wine']
list = (food[0] for food in food_list)

我们已经看到for循环的each形式

eat food for food in food_list

以及它的map形式

(food[0] for food in food_list)

下面给出它的filter形式

(food for food in food_list when food is 'wine')

列表解析的特色的地方在于它改变了我们组织循环的方式和解析数组的模式。这是一种声明式的编程方法,告诉程序你想要什么而不去关心构建的过程。

类的支持

类是CoffeeScript对JavaScript的一个很重要的补充。JavaScript的原型功能很强大,写法上又恨别扭。正确地设置原型链以实现继承关系也是个很大的挑战。CoffeeScript从语法上直接支持类的定义,自然且隐藏细节。

class Animal
 constructor: (@name) ->
 move: (meters) ->
  alert @name + " moved #{meters}m."
class Snake extends Animal
 move: ->
  alert "Slithering..."
  super 5
class Horse extends Animal
 move: ->
  alert "Galloping..."
  super 45
sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"
sam.move()
tom.move()

从实现上来说,CoffeeScript的类与JavaScript的构造函数和原型链那一套并无二致。所以,理解原型机制也是理解CoffeeScript类的基础。

关于JavaScript的糟粕

CoffeeScript的另一个目标是从语法层面上直接消除JavaScript的被人诟病的一些糟粕部分。前面已经说过关于分号的部分。关于var声明的部分。分号的机制暂且不去例会,总之CoffeeScript不用再去写分号了。

在JavaScript当中,最为人诟病的糟粕部分有两处,因为它们使用的情况最多而且容易出错。

全局变量

相等比较

全局变量

JavaScript的作用域规则很复杂,涉及到var声明机制和变量提升。在JavaScript里,构造一个全局变量是很容易的,有三种方式:

在全局的环境里用var声明

var name = 'name';

在函数内用省略var的方式定义

function foo() {
  name = 'name';
}

绑定到window的属性

window.name = 'name';

其中第1种和第2种方式是最常见的错误用法。首先不推荐直接在全局环境中编码,而是应该用一个匿名函数包裹起来,将程序的作用域限制在这个匿名函数中。第二种用法完完全全就是忘记了var声明。而我在实际的JavaScript编码中,忘记var声明是常有的事(就像经常忘记行末补上分号一样)。

而在CoffeeScript里面就完全没有这种担心了。首先,编译后的JavaScript代码不会暴露在全局环境里,所有的代码都是自动包裹在一个匿名函数(function(){ ... })();内。然后,所有的变量都会自动加上var声明。这就使得不小心污染全局的情况很难发生,除非使用赋值到window上。

相等比较

我们都知道JavaScript有两种比较运算符:==和===。我们也知道==在使用的过程中会很坑,所以平时都宁愿多打一个字符而使用===。CoffeeScript的只有一种比较运算符==,而它会编译成JavaScript的===,从而很好地避过了这道坑。

是否该使用CoffeeScript

CoffeeScript简化和增强了JavaScript的表达能力,尽可能地从语法层面上就能避免JavaScript的一些坑。用它写代码,会让人有更清晰舒适的感觉,而且不容易犯错。CoffeeScript的初衷就是提供更好的JavaScript。

然而,CoffeeScript与JavaScript是不兼容的。它既不是JavaScript的子集,也不是超集,而是与JavaScript有着显然不同思路的一种语言。用CoffeeScript编程就必然要转换观念,尽管这种观念更好更自然,但却是有些固步自封的人望而却步的主要原因了。

CoffeeScript并不是适合每一个人的。有些人对于用缩进组织代码层次完全不能接受,也不能接受用箭头函数表达法。对于他们来说,去掉function关键字和大括号的组织怎么看都怎么地不顺眼。

列表解析很强大,却也显得过于简洁了。对于习惯了构造冗杂JavaScript程序的人们来说,并不习惯这种表达方式。

总之,是不可强求别人去学习使用CoffeeScript。JavaScript已经足够强大,只要足够小心,完全可以使用JavaScript很好地完成工作。对于那些想要尝试CoffeeScript,我们也要给予鼓励的态度,他们是求新求变的勇士。CoffeeScript真的值得一试,而且它真的很小巧,完全掌握它不是件困难的事。

对于在团队推行CoffeeScript,我本人更是持有保守的看法。如果团队从一开始就使用CoffeeScript还好。如果是要从CoffeeScript转为JavaScript,就要谨慎行之。一种可行的方式是先尝试在一个小项目中使用CoffeeScrip,看看效果如何。

对于个人来说,就没有什么限制了。如果真的喜欢,就去尝试吧。你可以使用CoffeeScript写脚本,构建自己的网站,做一些小玩意。

以上内容是小编给大家介绍的使用CoffeeScrip优美方式编写javascript代码,希望大家喜欢。

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
从C/C到JavaScript:所有工作方式从C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript引擎:比较实施JavaScript引擎:比较实施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

超越浏览器:现实世界中的JavaScript超越浏览器:现实世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

使用Next.js(后端集成)构建多租户SaaS应用程序使用Next.js(后端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

如何使用Next.js(前端集成)构建多租户SaaS应用程序如何使用Next.js(前端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:22 AM

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript:探索网络语言的多功能性JavaScript:探索网络语言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的演变:当前的趋势和未来前景JavaScript的演变:当前的趋势和未来前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

神秘的JavaScript:它的作用以及为什么重要神秘的JavaScript:它的作用以及为什么重要Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。