多种语言

学习语言学习其优点

1.面向对象

比如说封装、继承、多态,Prototype,Mixin,Traits,Duck Typing 等
每个语言都一样,只在语法层面有所区别。

2.函数式编程

JVM 的 Lisp:Clojure

3.元编程

Java 的动态代理,CgLib 这些工具初步具备了元编程的能力,可以在运行时创建新的类;而 Ruby,Python 的开放性让它们的元编程更强一些,可以在运行时修改现有类,但是要想真正地理解元编程,还得去看 Lisp 的宏。尤其是,你要感受到代码即数据的强大力量

4.并发模型

Java 主要对线程做支持,还要学习其他并发模型,比如:Python有协程,Go有Go routine,Erlang采用的是 Actor。在这些并发模型中,还得考虑同步与互斥,锁,死锁,软件事物内存等技术。

5.虚拟机和垃圾回收

JVM 垃圾回收是个集大成者

6.静态类型,动态类型,类型推导

  • 静态类型的语言在编译器就能确定类型,编译器能帮忙发现错误,做些优化,但是会增加代码量;
  • 动态类型是在运行期才能发现错误。所谓动态一时爽,重构火葬场。
  • 类型推导在 Java10 就引入了

7.抽象语法树(AST)

几乎所有的主流编程语言,都要转换成AST 这么一个形式。有些语言还可以对 AST 做一些操作。

8.指针

指针是 C 语言的精华,虽然现在的 Java,Python,Ruby 等已经去掉了,但理解指针对理解计算机的底层运作大有好处。

9.其他

错误处理(异常),泛型,同步异步,序列化等

->、=>、$等符号的比对

符号 语言
a1,a2 -> codeint a,String b -> code groovy 传参
when(e){ a,b -> code [else->code]}when(e){is a -> code [else->code]} kotlin分支结构
(参数列表)-> code(参数列表)->{code} flutter
a1,a2 => {code}()=>{code} 微信小程序(js的箭头函数)
$name${name} groovy字符串内取值
$变量${对象.name}${数组[index]}${表达式} kotlin字符串内取值
$name${对象.name}$对象.$对象${数组[index]} flutter字符串内取值
{{name}} 微信小程序 数据绑定

Python和ES6语法差别

基本类型

JavaScript Python
Boolean true false True False
Nothing null None
Empty Value undefined
Number Number int float long complex
Sequences Array List tuple byte array buffer xrange
Key Value Store Object Dictionary

两者都是动态类型,但是 python 连接时并不会自动转换类型

1
2
3
//JavaScript
let coered = 1;
let concatenated = coered + 'string';
1
2
3
//Python
not_coerced = 1
concatenated = not_coerced + 'string' //直接报错:TypeError: cannot concatenate 'str' and 'int' objects
1
2
3
//Python 只有提前把num转换为字符串类型才能正确运行
not_coerced = 1
concatenated = str(not_coerced) + 'string'

Funtions or methods?

在 JavaScript 和 Python 中,函数和条件的结构极为相似。例如:

1
2
3
4
5
6
7
8
9
10
//JavaScript
function drSeuss(catInTheHat, thing1, thing2){
if(catInTheHat ==true && thing1 == true && thing2 == true){
co¬nsole.log('is cray');
} else if(catInTheHat != true){
console.log('boring');
} else {
console.log('so boring');
}
}
1
2
3
4
5
6
7
8
//Python
def dr_seuss(cat_in_the_hat, thing1, thing2):
if cat_in_the_hat == True and thing1 == True and thing2 == True:
print 'is cray'
elif cat_in_the_hat != True:
print 'boring'
else:
print 'so boring'

但在JavaScript中,“methods”的通俗定义是指语言规范中内置的方法,例如:Function.prototype.apply()

MDN上有对二者的解释:

在大多数方面,Functionsmethods相同,但有两个主要区别:

  • methods可以被隐式传递到调用该methods的对象上。
  • methods能够对类中包含的数据进行操作。

然鹅,在JavaScript中,“类”只是语法糖的存在,稍后我们再进行对比。

3. 模板字符串

在模板字符串上,JavaScript之前是领先于python的。

1
2
3
4
5
6
7
8
9
10
// JavaScript
let exclamation = 'Whoa!';
let sentence = `They are really similar to Python.`;

console.log(`Template Literals: ${exclamation} ${sentence}`);
复制代码
# python
print '打印: {} {}'.format('Whoa.', 'Quite!')
# 打印: Yup. Quite!
复制代码

{}充当占位符。 这种语法被诟病颇多,于是在后来的Python3.6版本中,又提供了一种字符串格式化语法——f-strings

直接对比:

1
2
3
4
5
name = "Tom"
age = 3
print(f"他叫 {name}, {age} 岁")
# "他叫Tom, 3 岁"
复制代码

4. 参数默认值

JavaScript再次完美“借鉴”Python:

1
2
3
4
5
6
7
8
9
10
11
12
13
// JavaScript
function nom(food="ice cream") {
console.log(`Time to eat ${food}`);
}

nom();// Time to eat ice cream
复制代码
# Python
def nom(food="ice cream"):
print 'Time to eat {}'.format(food)

nom() # Time to eat ice cream
复制代码

5. 其余参数和* args

Rest参数语法,使我们可以将不定数量的参数表示为数组,传入函数中。

  • Python中,它们称为* args
  • JavaScript...xxx就表示为其余参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// JavaScript
function joke(question, ...phrases) {
console.log(question);
for (let i = 0; i > phrases.length; i++) {
console.log(phrases[i]);
}
}

let es6Joke = "Why does JS single out one parameter?"
joke(es6Joke, "Because it doesn't", 'really like', 'all the REST of them!');

// Why does JS single out one parameter?
// Because it doesn't
// really like
// all the REST of them!
复制代码
# Python
def pirate_joke(question, *args):
print question
for arg in args:
print arg

python_joke = "What's a Pyrate's favorite parameter?"

pirate_joke(python_joke, "*args!", "*arrgs!", "*arrrgs!")

# What's a Pyrate's favorite parameter?
# *args!
# *arrgs!
# *arrrgs!
复制代码

6. Classes:类

众所周知,ES6类实际上是语法糖。 Python具有内置的类,可以快速,轻松地进行面向对象的编程。

JavaScript原型链继承,是每个前端的必须课。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// JavaScript
class Mammal {
constructor() {
this.neocortex = true;
}
}

class Cat extends Mammal {
constructor(name, years) {
super();
this.name = name;
this.years = years;
}

eat(food) {
console.log('nom ' + food);
}
}
复制代码
# Python
class Mammal(object):
neo_cortex = True

class Cat(Mammal):
def __init__(self, name, years):
self.name = name
self.years = years

def eat(food):
print 'nom %s' % (food)

fry_cat = Cat('Fry', 7)
fry_cat.eat('steak')
复制代码

平心而论,Python的写法更优雅。。。

7. Modules and import:模块

ES6的模块语言借鉴于python,却优秀于它。 两者之间有一些区别:

  1. JavaScript导入是静态的;Python是动态的。
  2. JavaScript模块必须显式导出。在Python中,所有模块均可导入。
  3. JavaScript具有默认导出的概念。Python没有。
1
2
3
4
5
6
7
8
# python
import mymodule
mymodule.myfunc()
复制代码
// javascript
import * as myalias from "./mymodule";
myalias.myfunc();
复制代码

1. 导入分模块

javascript中,我们想导入分模块直接解构赋值就可以了

1
2
3
4
5
// javascript
import { myvar, myfunc } from "./mymodule";
console.log(myvar);
myfunc();
复制代码

而在python,其语义则相反:

1
2
3
4
5
# python
from mymodule import myvar, myfunc
print myvar
myfunc()
复制代码

2. 导出空函数

如何想导出一段空函数,python需要用到“pass“关键词占位,避免运行出错。 mymodule.py:

1
2
3
4
5
6
# python
def myfunc(): pass

// javascript
export function myfunc() {}
复制代码

更多详细对比可以看这篇: Modules and import in ES6 for Python developers