检查值是否存在

使用存在运算符

CoffeeScript中有一个非常有用的存在运算符?,它能正确地处理值是否存在(存在的意思为变量不为undefined或者null)的情况。在变量后添加?来判断它是否存在。

注意,如果?运算符后没有参数,那么在使用?运算符时必须紧靠在标识符后,不能有空格,否则会按照函数调用编译,编译出错。

if yeti?
'I want to believe'
###
上面的代码被编译为:
if(typeof yeti != null){
'I want to believe'
}
###

在链式调用中

通过在链式调用中使用?可以防止空值造成类型错误,同时,这样做也无法对不同层次的属性的不存在分别处理。

tree =
pine:
type: 'evergreen'
crabapple:
type: 'deciduous'
fruit:
ediable: false
if trees.pine.fruit?.edible
console.log "Mmm.. pine fruit"

对于数组和函数调用,也可使用?运算符。

# 数组
alpha =
lowercase: ['a','b','c','d']
console.log alpha.lowercase?[2].toUpperCase() # 执行
console.log alpha.uppercase?[2].toLowerCase() # 不执行 # 函数
oppositeMath =
min: Math.max
console.log oppositeMath.min?(3.2.5) # 执行
console.log oppositeMath.max?(3,2,5) # 不执行

以空值为条件,赋新值

brief = null
breif ?= 2 # breif为2

上面的例子中需要注意的是:?=运算符左侧不能使用未声明的变量,否则编译会出错,因为变量不是有效引用。?运算符不受此约束。

||和比较运算符都被扩展了,也就是说||=or=都是合法的。

一次给多个变量赋值

CoffeeScript提供了解构赋值的功能,即只用一个表达式,就可以实现给数组或者对象中的多个变量赋值。

[first, second] = ["home","cart"]
[first, second] = [second, first] # 变量替换
[drink,[alcohol, mixer]] = ["Screwdriver", ["vodka", "orange juice"]] #

同时,我们可以在使用返回数组(多个值)的函数时使用。

[languageName, prefix] = "CoffeeScript".match /(.*)Script/
console.log "I love the smell of #{prefix} in the morning."

同时,解构赋值还可以用于对象,将变量付给特定名字,具体有两种用法:

  • {property} = object ,其中,property为对象中属性的名字,复制后成为单独的变量可以直接使用
  • {property: identifier} = object, 其中,property为对象中属性的名字,identifier为给定的变量名(可以事先不声明)。赋值之后identifier的值变成对象中property对应的值。
bird = verb: 'singing', time: 'midnight'
{time} = bird # time为'midnight'
{time:timeOfDate} = bird # timeOfDate为'midnight'

同时,可以互相嵌套对象,还可以在对象中嵌套数组。

# 使用对象嵌套赋值
direction = [
{type: 'boat', directions: ['port', 'starboard']}
{type: 'dogsled', directions: ['haw', 'gee']}
] [boatInfo, {directions: [left, right]}] = direction console.log 'boatInfo: ' + boatInfo.type # 输出 boatInfo: boat
console.log 'left: ' + left + '; right: ' + right # 输出 left: haw; right: gee

高级函数参数

默认参数值

CoffeeScript中的函数支持默认函数参数。

func = (a, b = 'b') ->
console.log a + ',' + b func 'a' # 输出 a,b
func 'a', null # 输出 a,b
func 'a', 'c' # 输出 a,c

接受可变参数的splat

在函数定义的参数后添加...,即将此参数声明为可接受任意数目参数的变量。

func2 = (a,b...)->
console.log b.length func2 1,2,3,4 # 输出 3

可变参数不一定要在参数列表最后一个。同时,解构赋值也可以使用可变参数。

[race, [splits..., time]] = ['10K',['13:08','13:09','23:17']]

console.log race    # 输出 10K
console.log splits # 输出 ['13:08','13:09']

调用函数时使用splat

不仅可以在定义函数时使用splat,而且还可以在调用函数时使用splat。

# 调用函数时使用splat
func3 = (a,b,c) ->
len = arguments.length
console.log len
if len == 1
a
else if len == 2
a + ',' + b
else if len == 3
a + ',' + b + ',' + c
else
'null' arr = [1,2,3]
console.log func3 arr...
###
输出:
3
1,2,3
### # 被调用函数内部使用splat
func4 = (a,b...) ->
console.log Math.min b... func4 1, 2, 3, 4 # 输出2

调用splat总结:

  • splat总是让你处理一个数组
  • splat为函数的参数,那么以数组的形式给出,同时,也可在函数内部将splat形式的参数用来调用函数,如func4所示
  • 以splat形式调用函数,以数组的方式调用,函数接收到的为分开的值

《CoffeeScript应用开发》学习: 第四章-改进应用程序的更多相关文章

  1. Android艺术开发探索第四章——View的工作原理(下)

    Android艺术开发探索第四章--View的工作原理(下) 我们上篇BB了这么多,这篇就多多少少要来点实战了,上篇主席叫我多点自己的理解,那我就多点真诚,少点套路了,老司机,开车吧! 我们这一篇就扯 ...

  2. Knockout应用开发指南 第四章:模板绑定

    原文:Knockout应用开发指南 第四章:模板绑定 模板绑定The template binding 目的 template绑定通过模板将数据render到页面.模板绑定对于构建嵌套结构的页面非常方 ...

  3. Java基础知识二次学习--第四章 异常

    第四章 异常处理   时间:2017年4月26日11:16:39~2017年4月26日11:28:58 章节:04章_01节 04章_02节 视频长度:20:46+01:16 内容:异常的概念 心得: ...

  4. C#高级编程 (第六版) 学习 第四章:继承

    第四章 继承 1,继承的类型 实现继承: 一个类派生于一个基类型,拥有该基类型所有成员字段和函数. 接口继承 一个类型只继承了函数的签名,没有继承任何实现代码.   2,实现继承 class MyDe ...

  5. 4类Storage方案(AS开发实战第四章学习笔记)

    4.1 共享参数SharedPreferences SharedPreferences按照key-value对的方式把数据保存在配置文件中,该配置文件符合XML规范,文件路径是/data/data/应 ...

  6. 菜单Menu(AS开发实战第四章学习笔记)

    4.5 菜单Menu Android的菜单主要分两种,一种是选项菜单OptionMenu,通过按菜单键或点击事件触发,另一种是上下文菜单ContextMenu,通过长按事件触发.页面的布局文件放在re ...

  7. java并发学习--第四章 JDK提供的线程原子性操作工具类

    在了解JDK提供的线程原子性操作工具类之前,我们应该先知道什么是原子性:在多线程并发的条件下,对于变量的操作是线程安全的,不会受到其他线程的干扰.接下来我们就学习JDK中线程的原子性操作. 一.CAS ...

  8. 《Android深度探索HAL与驱动开发》第四章阅读心得

     Android源代码包含了很多内容,可以实现拍照.计算机.日历.相册.拨号器等功能.配置Android源代码下载环境需要如下几步: (1)创建一个用于存放下载脚本文件的目录:  (2)下载repo脚 ...

  9. Android艺术开发探索第四章——View的工作原理(上)

    这章就比较好玩了,主要介绍一下View的工作原理,还有自定义View的实现方法,在Android中,View是一个很重要的角色,简单来说,View是Android中视觉的呈现,在界面上Android提 ...

随机推荐

  1. C# List 的一些操作 (两List元素是否想同,List是否包含在另一个List中)

    一. 假设有两个List<T>对象 ,List1和List2,如下方法判断两个List是否相等 List1.All(List2.Contains) && List1.Cou ...

  2. Validation failed for one or more entities.

    验证失败后用DbEntityValidationException 查找出错的字段 try { // Your code... // Could also be before try if you k ...

  3. PetShop安装失败

    报错提示: Security This installer has encountered an unexpected error installing this package. This may ...

  4. SQL:实现流水账的收入、支出、本期余额

    有多组数据,分别是收入,支出,余额,它们的关系是:本期余额=上次余额+收入-支出 /* 测试数据: Create Table tbl([日期] smalldatetime,[收入] int ,[支出] ...

  5. Android SQLite 通配符查询找不到参数问题

    使用Android SQLite中SQLiteDatabase类的query方法查询时,如果where中包含通配符,则参数会无法设置,如类似下面的方法查询时 SQLiteDatabase db = d ...

  6. [经验交流] docker in docker 的变通实现方法

    最近在做CI持续集成环境的容器化,其中一个工作是:在容器中构建容器镜像. 对于这个需求,网上有一些 Docker in Docker 的方法,具体需要修改宿主机的配置.这种方式在单机环境下.对安全要求 ...

  7. 在Eclipse中使用JUnit4进行单元测试(中级篇)

    我们继续对初级篇中的例子进行分析.初级篇中我们使用Eclipse自动生成了一个测试框架,在这篇文章中,我们来仔细分析一下这个测试框架中的每一个细节,知其然更要知其所以然,才能更加熟练地应用JUnit4 ...

  8. 在shiro-cas中实现 Jasig-cas的Single Sign Out 功能

    1 Single Sign Out 功能 即单点登出功能.也就是在任意子系统进行登出操作后,其他子系统会自动登出. 实际CAS登出的步骤为 所以每个子系统都需要实现一个sso登出响应. cas-cli ...

  9. 每天一个 Linux 命令(17):whereis 命令

    whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b).man说明文件(参数-m)和源代码文件(参数-s).如果省略参数,则返回所有信息. 和find相比,whereis查找的速度非 ...

  10. Python基础篇【第5篇】: Python内置模块(二)

    内置模块 1. OS os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相当于shell ...