共计 2356 个字符,预计需要花费 6 分钟才能阅读完成。
近来想拓展一下技能,感觉 Flutter 挺有奔头,所以就扎进来了,但要应用 Flutter 必先学会 Dart。粗略看了一下,Dart 在计上与 JS 很像:事件驱动、单线程环境、相熟的
var
/const
关键字……
既然我曾经学会 JS 了,从 开掘两种语言的共同点并带入相干的不同点 动手可能是一种不错的学习计划,也能够顺道温习一下 JS。如无非凡阐明,本文中的 JS 包含 ES5 至 ES2021 的全副个性。
当然,这系列文章更多的是自学者的一些见解,疏漏和舛误不免,如果诸君慧眼识虫,望不吝指正。
一、函数模式
1. 一般函数
相同之处
- JS 和 Dart 的一般函数构造类似:函数申明,前面是函数名,而后别离是以圆括号
()
包裹、以逗号,
辨别的参数列表,最初是以花括号{}
包裹的函数体; - JS 反对应用
=
指定函数参数的默认值,新版 Dart 也反对这一语法; -
JS 能够应用对象作为参数,从而规定该对象的某些值,Dart 也反对形似的语法(不过调用函数的时候传值计划不太一样,前面详说)。
// 能够看出和 JS 的函数很像 // 把 int 改成 function 就是了 int foo(a = 1, b = 2){return a + b;}
不同之处
申明关键字不同
- JS 中的一般函数须以
function
关键字申明; -
Dart 中的一般函数以返回类型申明开始,也能够缺省。
// 缺省返回类型,交给 Dart 推断 /*int*/ foo(a = 1, b = 2){return a + b;}
JS 不反对类型申明
- JS 不反对类型申明,因而返回值和参数的类型只有在运行时才会确定;
-
Dart 反对类型申明,能够指定返回值与参数的类型,但均能够缺省。
// 下面省略了参数类型申明,这里把它补上 int foo(int a = 1, int b = 2){return a + b;}
可选参数
- Dart 函数可应用一个
[]
包裹其参数列表尾部的可选参数,所有未标为required
的命名参数都是可选参数; -
JS 的所有参数(除了作为命名参数载体的对象及其后面的地位参数之外)都是可选参数。
// Dart 地位参数 foo(int a = 1, [int b = 2]){return a + b;} // Dart 命名参数 foo({required a, b = 2}){return a + b;}
命名参数的传入计划
-
如前所述,JS 的命名参数实际上是应用对象占位,所以调用函数的时候,间接在对应地位传入一个对象即可:
function testFunc(a, {b = 1}){return a + b;} testFunc(a, {b: 2}); // 3
;
-
Dart 的命名参数是纯正的语法,调用函数的时候用
name: value
的形式指定:int testFunc(a, {b = 1}){return a + b;} testFunc(a, b : 2); // 3
。
相比之下 Dart 的语法仿佛比拟简洁,然而初见的时候多少有些不习惯。
其余
- 在某个例子里,我仿佛瞥见了
foo.call
,看来某些 JS 的“精粹”也被 Dart 借用了,不晓得二者有多大的相似之处; - JS 中没有可变参数的概念,但咱们都晓得能够用
arguments
或者[...args]
拜访函数的全副参数,这是在开发中应用高阶函数 (HOC
) 的根底,然而我暂未看到相似的Dart
语法,不晓得 Dart 有无对应的应用办法; - 两种语言中的匿名函数的异同点根本与命名函数统一,按下不表。
- 提到 JS 就不得不说那迷人又该死的
this
指向,侥幸的是 Dart 的一般函数没有这个货色(欢呼)! -
JS 的命名函数能够在申明的同时赋给一个变量,然而在 Dart 中只能对匿名函数这么做:
// 把正文去掉,是无奈通过编译的 var testFunc = /*funcName*/ (){}; // 这里的分号不可或缺,这是其余的知识点
。
2. 箭头函数
相似之处
- 两者的语法都是
(参数列表) => {表达式}
; - 花括号
{}
都能够省略。
不同之处
圆括号不可省
-
JS 的箭头函数,如果只有一个参数的话,参数列表外能够不套圆括号:
const testFunc = a => a++;
;
- Dart 的箭头函数必须用圆括号包含参数列表。
只能写一个表达式
- 严格来说这不是箭头函数的语法差别,因为在 JS 中,用花括号包裹起来的所有代码块都视作一个表达式,所以箭头函数能够无所不包;
-
但在 Dart 中,貌似花括号失去了上述“魔力”,表达式的真正分界是分号
;
,尽管用逗号能够隔开多个语句,然而仍无奈再申明任何两头变量了:var testFunc = (start, {end = 7}) => { // 去掉这个正文,编译将无奈通过 /*int finalEnd */= start + end, for(num i = start; i < end; i++){display((i + 1).toString()) } };
。
-
如果你想在箭头函数中多放些语句,能够用一个
IIFE
包裹起来:var testFunc = (start, {end = 7}) => (() { var finalEnd = start + end; for(num i = start; i < finalEnd; i++){display((i + 1).toString()); } })();
,嗯……让人不由得想起某个 ES5 的经典面试题。
二、程序入口
Dart 须要 main 函数
- 家喻户晓,JS 是没有入口函数的,在以后执行上下文中“裸泳”的表达式会间接被执行,而 JS 的顶层作用域也是第一个执行上下文。
-
不过 Dart 并不阻止你在全局作用域写表达式——前提是把它们写在变量申明语句里:
vaoi main(){} var a = 3 + 2 - 5 * 0;
,
-
Dart 也不阻止你在全局调用函数——然而这个语句可能在编译时优化掉了:
vaoi main(){} testFunc(){print('called me'); } var testVar = testFunc(); // 控制台空洞无物
(当然这可能是 web 版
DartPad
的特色,其余语法查看器件 / 编译器可能会报错的,标准之外的 sao 操作倡议还是少做一点比拟好)。