The LiveScript Book
The LiveScript Book
操作符
数字
标准的数学操作符:
1.1 + 2 # => 3
2.3 - 4 # => -1
3.6 * 2 # => 12
4.8 / 4 # => 2
取模运算符:
1.-3 % 4 # => -3
2.-3 %% 4 # => 1
幂运算符是右结合的,比一元运算符优先级高。^
是**
的语法糖:
1.2 ** 4 # => 16
2.3 ^ 4 # => 81
3.-2 ^ 2 ^ 3 # => -256
自增与自减运算符与 JavaScript 中的一样。
位运算:
1.14 .&. 9
2.14 .|. 9
3.14 .^. 9
4.~9
5.9 .<<. 2
6.-9 .>>. 2
7.-9 .>>>. 2
1.14 & 9;
2.14 | 9;
3.14 ^ 9;
4.~9;
5.9 << 2;
6.-9 >> 2;
7.-9 >>> 2;
转换到数字
1.+'4' # => 4
2.-'3' # => -3
1.+'4';
2.-'3';
比较运算符
严格相等比较:
1.2 + 4 == 6 # => true
2.\boom is 'boom' # => true
3.
4.\boom != null # => true
5.2 + 2 is not 4 # => false
6.0 + 1 isnt 1 # => false
1.2 + 4 === 6;
2.'boom' === 'boom';
3.'boom' !== null;
4.2 + 2 !== 4;
5.0 + 1 !== 1;
弱相等比较:
1.2 ~= \2 # => true
2.\1 !~= 1 # => false
1.2 == '2';
2.'1' != 1;
大于/少于:
1.2 < 4
2.9 > 7
3.8 <= 8
4.7 >= 8
链式比较:
1.1 < 2 < 4
2.1 < 2 == 4/2 > 0
转译后的 JavaScript
1.var ref$;
2.1 < 2 && 2 < 4;
3.1 < 2 && 2 === (ref$ = 4 / 2) && ref$ > 0;
取大/取小
运算
1.4 >? 8
2.9 - 5 <? 6
1.var ref$;
2.4 > 8 ? 4 : 8;
3.(ref$ = 9 - 5) < 6 ? ref$ : 6;
当==
或者 is
的一边是一个正则表达式时,另一边将被这个正则表达式测试,等价地转换成exec
,
所以你可以直接使用测试后的结果,!=
或者isnt
转译为test
。
1.'enter' is /^e(.*)/
2./^(.*)/ == 'zx'
3./moo/ != 'loo'
1./^e(.*)/.exec('enter');
2./^(.*)/.exec('zx');
3.!/moo/.test('loo');
逻辑运算符
基本的逻辑运算符:
1.true and false
2.true && false
3.
4.true or false
5.true || false
6.
7.not false
8.!false
1.true && false;
2.true && false;
3.true || false;
4.true || false;
5.!false;
6.!false;
与其他语言不同的一个逻辑运算符是异或
:
1.false xor true # => true
2.false xor false # => false
3.1 xor 0 # => 1
4.1 xor 1 # => false
1.!false !== !true && (false || true);
2.!false !== !false && (false || false);
3.!1 !== !0 && (1 || 0);
4.!1 !== !1 && (1 || 1);
and
,or
,and xor
闭合函数调用的传参,但是||
和&&
不会。
1.even 0 and 3 # => 3
2.even 0 && 3 # => true
1.even(0) && 3;
2.even(0 && 3);
你可以调用逻辑运算符。
1.(f or g) 1
2.(f and g or h) 3 4
1.f(1) || g(1);
2.f(3, 4) && g(3, 4) || h(3, 4);
In/Of
使用in
检查是否一个元素存在于列表中,使用of
检测key
是否存在于对象中。
1.list = [ 7 8 9 ]
2.2 in [ 1 2 3 4 5 ]
3.3 in list
4.\id of id: 23, name: \rogers
1.var list;
2.list = [7, 8, 9];
3.2 === 1 || 2 === 2 || 2 === 3 || 2 === 4 || 2 === 5;
4.in$(3, list);
5.'id' in {
6. id: 23,
7. name: 'rogers'
8.};
9.
10.function in$(x, xs) {
11. var i = -1,
12. l = xs.length >>> 0;
13. while (++i < l)
14. if (x === xs[i]) return true;
15. return false;
16.}
管道
除了函数直接嵌套调用,你还可以使用试用管道进行函数嵌套调用。x |> f
和f <| x
都等价于f(x)
。
1.x = [ 1 2 3 ] |> reverse |> head
2.
3.y = reverse <| [ 1 2 3 ]
1.var x, y;
2.x = head(
3. reverse(
4. [1, 2, 3]));
5.y = reverse([1, 2, 3]);
你可以换行使得结果更加清晰。
1.4
2.|> (+ 1)
3.|> even
1.even(
2. (function(it) {
3. return it + 1;
4. })(
5. 4));
函数
函数组合运行你创建一系列的函数并将它们组合起来使用。 LiveScript 有两种操作符,>>
和>>
可以用来进行函数组合。
(f << g) x
等价于f(g(x))
,(f >> g) x
等价于g(f(x))
。例如:
1.odd = (not) << even
2.odd 3 # => true
1.var odd;
2.odd = compose$(even, not$);
3.odd(3);
4.
5.function compose$() {
6. var functions = arguments;
7. return function() {
8. var i, result;
9. result = functions[0].apply(this, arguments);
10. for (i = 1; i < functions.length; ++i) {
11. result = functions[i](result);
12. }
13. return result;
14. };
15.}
16.
17.function not$(x) {
18. return !x;
19.}
下面的例子将更加清晰的阐述这两个运算符的区别:
1.add-two-items-two = (+ 2) >> (* 2)
2.times-two-add-two = (+ 2) << (* 2)
3.
4.add-two-items-two 3 # => ( 3 + 2 ) * 2
5.times-two-add-two 3 # => ( 3 * 2 ) + 2
你也可以使用Haskell
中类似的.
来替代<<
,例如: f . g
。
列表
你可以连接两个list
:
1.<[ one two three ]> ++ [\four]
1.['one', 'two', 'three'].concat(['four']);
注意 列表连接符与操作数之间要么两边都留空,要么都不留空!否则将被视为自增运算符
表重复操作
1.[\hei] * 3
1.['hei', 'hei', 'hei'];
Join
操作
1.<[ one two three ]> * \|
1.['one', 'two', 'three'].join('|');
一元运算展开-当运算对象是表字面量时,对表每一项使用该运算符。
1.r = +[ 4 5 6 ]
2.
3.t = typeof! [ \b 5 {} ]
4.
5.c = ~[ 4 5 ]
6.
7.++player<[ strenth hp ]>
8.
9.i = new [ some, classes ]
10.
11.c = ^^[ copy, these, {} ]
12.
13.delete list[ 1 2 3 ]
14.
15.do [ a, b, c ]
1.var r, t, c, i, toString$ = {}.toString;
2.
3.r = [+4, +5, +6];
4.
5.t = [toString$.call('b').slice(8, -1), toString$.call(5).slice(8, -1),
6. toString$.call({}).slice(8, -1)];
7.
8.c = [~4, ~5];
9.
10.++player['strenth'], ++player['hp'];
11.
12.i = [new some, new classes];
13.
14.c = [clone$(copy), clone$(these), clone$({})];
15.
16.delete list[1], delete list[2], delete list[3];
17.
18.a(), b(), c();
19.
20.function clone$(it) {
21. function fun() {}
22. fun.prototype = it;
23. return new fun;
24.}
字符串
字符串连接:
1.'hello' + ' ' + 'world'
2.string = 'say '
3.string += \yeah
1.var string;
2.'hello' + ' ' + 'world';
3.string = 'say ';
4.string += 'yeah';
字符串重复当第一个操作数是字符串字面量时:
1.'xy' * 3
1.'xyxyxy';
字符串的减
和除
,当右边的操作数是一个字符串或者是一个正则表达式。
-
等价于replace
,/
等价于 split
。
1.'say yeah' - /h/ # => say yea
2.'say yeah' / \y # => ["sa", " ", "eah"]
1.'say yeah'.replace(/h/, '');
2.'say yeah'.split('y');
存在运算符
?
运算符可以用于在各种上下文环境中检测存在否。
1.bigfoot ? 'grizzly bear'
2.
3.string = \boom if window ?
4.
5.document ? .host
1.var string;
2.(typeof bigfoot == 'undefined' || bigfoot === null) && 'grizzly bear';
3.if (typeof window != 'undefined' && window !== null ? window :
4.typeof document != 'undefined' && document !== null ? document.host : void 8) {
5. string = 'boom';
6.}
对象
instanceof
的右边如果是列表,那么会展开。
1.new Date() instanceof Date
2.
3.new Date() instanceof [ Date, Object ]
1.var ref$;
2.new Date() instanceof Date;
3.(ref$ = new Date()) instanceof Date || ref$ instanceof Object;
typeof
的右边添加一个惊叹号,表示一个选择。
1.typeof /^/
2.typeof! /^/
1.var toString$ = {}.toString;
2.typeof /^/;
3.toString$.call(/^/).slice(8, -1);
delete
删除对象的某个成员,并返回该成员的值:
1.obj = {one: 1, two: 2}
2.r = delete obj.one
3.r # => 1
delete!
像 JavaScript 中的 delete
,如果成员的某个属性存在并且可以被删除,就返回true
,否则返回false
。
1.obj = {one: 1, two: 2}
2.delete! obj.one # => true
3.delete! Math.PI # => false
属性拷贝-使用<<<
把操作符右边的可枚举且属于自己的属性拷贝到最左边的对象上, <<<<
可以用来拷贝所有属性。 import
和 import all
用来将给出的对象拷贝到当前this
对象上。
1.obj = {one: 1}
2.obj2 = {two: 2}
3.obj3 = {three: 3}
4.obj <<< obj2 <<< obj3
5.
6.console.log obj # => Object {one: 1, two: 2, three: 3}
7.console.log obj2 # => Object {two: 2}
8.console.log obj3 # => Object {three: 3}
9.
10.import obj
11.
12.console.log @three # => 3
1.var obj, obj2, obj3;
2.obj = {
3. one: 1
4.};
5.obj2 = {
6. two: 2
7.};
8.obj3 = {
9. three: 3
10.};
11.import$(import$(obj, obj2), obj3);
12.console.log(obj);
13.console.log(obj2);
14.console.log(obj3);
15.import$(this, obj);
16.console.log(this.three);
17.
18.function import$(obj, src) {
19. var own = {}.hasOwnProperty;
20. for (var key in src)
21. if (own.call(src, key)) obj[key] = src[key];
22. return obj;
23.}
克隆-对被操作对象进行原型级的克隆,并没有进行深度克隆,只是对结果的原型链进行引用赋值。JSON
序列化时会忽略掉这些克隆而来的属性。
1.obj =
2. one: 1
3.
4.obj2 = ^^obj
5.obj2.two = 2
6.obj2 # => {one: 1, two: 2}
7.#上面只是修改了原型链的指向
8.#JSON化将只有{one: 1}
9.
10.obj # => {one: 1}
11.
12.obj.one = 3
13.console.log obj2.one # => 3
1.var obj, obj2;
2.obj = {
3. one: 1
4.};
5.obj2 = clone$(obj);
6.obj2.two = 2;
7.obj2;
8.obj;
9.obj.one = 3;
10.console.log(obj2.one);
11.
12.function clone$(it) {
13. function fun() {}
14. fun.prototype = it;
15. return new fun;
16.}
局部应用,操作符用作函数
你可以局部的将操作符做为函数来使用:
1.(+ 2) 4 # => 6
2.(*) 4 3 # => 12
3.
4.(not) true # => false
5.(in [1 to 3]) 2 # => true
export
通过使用export
来替代exports
,可以更加方便的定义模块。
1.export func = ->
2.
3.export value
4.
5.export value-a, value-b, value-c
6.
7.export
8. a: 1
9. b: -> 123
10.
11.export class MyClass
1.var func, ref$, MyClass, out$ = typeof exports != 'undefined' && exports || this;
2.out$.func = func = function() {};
3.out$.value = value;
4.out$.valueA = valueA;
5.out$.valueB = valueB;
6.out$.valueC = valueC;
7.ref$ = out$;
8.ref$.a = 1;
9.ref$.b = function() {
10. return 123;
11.};
12.out$.MyClass = MyClass = (function() {
13. MyClass.displayName = 'MyClass';
14. var prototype = MyClass.prototype,
15. constructor = MyClass;
16.
17. function MyClass() {}
18. return MyClass;
19.}());
require
包含一系列的模块通常导致一堆麻烦。使用require!
可以帮你避免掉这些不必要的麻烦,
需要传给require!
一个ID
、一个字符串
或者一个对象字面量
。
如果你要使用一个名称中含有破折号的模块,你得使用字符串字面量
。对象字面量
可以让你重命名你所引用的模块。 你可以对值进行析构。
1.require! lib
2.
3.require! 'lib1'
4.
5.require! 'prelude-ls'
6.
7.require! [fs, path]
8.
9.require! <[ fs path ]>
10.
11.require! jQuery : $
12.
13.require! {
14. fs
15. path
16. lib: foo
17.}
1.var lib, lib1, preludeLs, fs, path, $, foo;
2.lib = require('lib');
3.lib1 = require('lib1');
4.preludeLs = require('prelude-ls');
5.fs = require('fs');
6.path = require('path');
7.fs = require('fs');
8.path = require('path');
9.$ = require('jQuery');
10.fs = require('fs');
11.path = require('path');
12.foo = require('lib');
使用析构,你可以非常方便的使用模块中的部分内容。
1.require! {
2. fs: filesystem
3. 'prelude-ls': {map, id}
4. path: {join, resolve}:p
5.}
1.var filesystem, ref$, map, id, p, join, resolve;
2.filesystem = require('fs');
3.ref$ = require('prelude-ls'), map = ref$.map, id = ref$.id;
4.p = require('path'), join = p.join, resolve = p.resolve;
文件名会被自动提取的。
1.require! 'lib.js'
2.require! './dir/lib1.js'
1.var lib, lib1;
2.lib = require('lib.js');
3.lib1 = require('./dir/lib1.js');