了解该语言的基本数据类型,基本语法和主要语言构造;主要数学运算符和print函数的使用,达到能够写课后习题水平; print函数: 一共有4种
1 2 3 4 5 6 7 window .alert("this is window.alert" );document .getElementById("demo" ).innerHTML = "we can use innerHTML to modify the demo id" ;document .write("we can also use write function to write to html" );console .log("we can also print it to console" );
基本语法:
变量使用let, const
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 let i = 5 let j = "this is string" let k = [1 ,2 ,3 ,4 ,5 ] let myMap = new Map (); let keyString = "key" ; myMap.set(keyString, "value" ); myMap.get(keyString); myMap.get("key" ); let h = { "first" : "1" , "second" : "2" } let m = () => { console .log("this is function" ) } class Example { constructor (a ) { this .a = a; } } let example = new Example();
算术操作符,和C语言一样:
javascript的数据类型: 因为将16从number转换成为了string
1 2 3 4 16 + "Volvo" "16Volvo"
其次掌握数组和其他集合类的使用,有基础的话可以理解一下泛型,如果理解不了也问题不大,后面可以补; 将string转换为number:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Number .parseInt('12.34' ); Number .parseInt(12.34 ); Number .parseFloat('123.45' ) Number .parseFloat('123.45abc' ) Number .parseFloat('abc' ) Number .isInteger(value)Number .isInteger(0 ); Number .isInteger(1 ); Number .isInteger(1.0 ); Number .isInteger(1.1 ); Number .isInteger(Math .PI);
math对象需要掌握的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Math .trunc(12.3 ); Math .trunc(12 ); Math .trunc(-0.5 ); Math .trunc(0.5 ); Math .trunc("12.3" ); Math .trunc(); Math .trunc(NaN ); Math .trunc("hhh" ); Math .trunc("123.2hhh" ); Math .random() Math .floor() Math .floor(Math .random()* 100 );
string需要掌握的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 let txt = "Hello World!" ;let len = txt.length;let str="Hello world!" ;console .log(str.substring(3 )+"<br>" );console .log(str.substring(3 ,7 ));let string = "apple,banana,orange" ;string.includes("banana" ); let str="Hello world, welcome to the universe." ;let n=str.indexOf("welcome" );let str="Visit Microsoft! Visit Microsoft!" ;let n=str.replace("Microsoft" ,"Runoob" );let str="Mr Blue has a blue house and a blue car" ;let n=str.replace(/blue/g ,"red" );
数组需要掌握的方法:
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 35 36 37 let fruits = ["Banana" , "Orange" , "Apple" , "Mango" ];let len = fruits.length;[1 , 2 , 3 ].includes(1 ); [1 , 2 , 3 ].includes(1 , 2 ); [1 , NaN , 3 ].includes(NaN ); fruits.push("Hola" ); let myStringArray = ["Hello" ,"World" ];let arrayLength = myStringArray.length;for (let i = 0 ; i < arrayLength; i++) { console .log(myStringArray[i]); } let numbers = [4 , 9 , 16 , 25 ];function myFunction (item, index ) { console .log("item is " + item + ", index is" + index); } numbers.forEach(myFunction) let colors = ['red' , 'green' , 'blue' ];for (const color of colors){ console .log(color); }
map需要掌握的方法:
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 35 36 37 38 39 40 41 42 43 let myMap = new Map ();myMap.set(0 , "zero" ); myMap.set(1 , "one" ); myMap.forEach(function (value, key ) { console .log(key + " = " + value); }, myMap) let myMap = new Map ();myMap.set(0 , "zero" ); myMap.set(1 , "one" ); for (let [key, value] of myMap) { console .log(key + " = " + value); } for (let [key, value] of myMap.entries()) { console .log(key + " = " + value); } for (let key of myMap.keys()) { console .log(key); } for (let value of myMap.values()) { console .log(value); } if (myMap.get("key" ) === undefined ) { }
简单字符串处理。所谓简单,就是Regex和Parser以下的内容,什么查找替换,截断去字串之类的。不过这个阶段有一个难点,就是字符编码问题。如果理解不了,可以先跳过,否则的话最好在这时候把这个问题搞定,免留后患;
基本面向对象或者函数式编程的特征,无非是什么继承、多态、Lambda函数之类的,如果有经验的话很快就明白了; 1 2 3 4 5 6 7 在 JavaScript 的现实场景中,尤其是前端代码,我们很少真正用到类继承,大多数时候,工厂函数就能完成我们的目标。 以React为例,官方这几年推崇 Hooks 的意图也很明显 —— 摆脱JavaScript class 带来的复杂性,拥抱函数式风格。 由于 JavaScript 实现的特殊性,在 JavaScript 应用中使用 class 对于一些程序员来说有许多坑,于此同时,大多数场景下其他替代方案如 工厂函数 可能更契合JavaScript 的特性,反而带来更好的效果。 当然,并不是一杆子打死 JavaScript 的 class ,在一些特别适合 OOP 的场景中,依然鼓励使用 class 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Point { constructor (x, y ) { this .x = x; this .y = y; } toString ( ) { return x.toString() + ' ' + y.toString(); } } class ColorPoint extends Point { constructor (x, y, color ) { super (x, y); this .color = color; } toString ( ) { return this .color + ' ' + super .toString(); } }
1 2 3 4 5 6 7 8 9 10 function ListNode (val ) { this .val = (val===undefined ? 0 : val) } let node1 = new ListNode(1 );console .log(node1.val);
异常、错误处理、断言、日志和调试支持,对单元测试的支持。你不一定要用TDD,但是在这个时候应该掌握在这个语言里做TDD的基本技能; 1 2 3 4 nodejs 语言里面没有自带unit test,但是可以使用Test Framework, 可以使用Jest https :
程序代码和可执行代码的组织机制,运行时模块加载、符号查找机制,这是初学时的一个难点,因为大部分书都不太注意介绍这个极为重要的内容 1 2 3 4 5 6 使用任何语言进行编程都有一个类似的问题,那就是如何组织代码,具体来说,如何避免命名冲突?如何合理组织各种源文件?如何使用第三方库?各种代码和依赖库如何编译连接为一个完整的程序? 比如java是使用包的机制 但是JavaScript是使用module ,
一个模块就是一个独立的文件, 该文件内部的所有变量,外部无法获取。
1 2 3 4 5 6 let firstName = 'Michael' ;let lastName = 'Jackson' ;let year = 1958 ;export { firstName, lastName, year };
使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。
1 2 3 4 5 6 7 8 9 10 11 12 import { firstName, lastName, year } from './profile.js' ;import { lastName as surname } from './profile.js' ; import { stat, exists, readFile } from 'fs' ; import * as circle from './circle' ; function setName (element ) { element.textContent = firstName + ' ' + lastName; }
nodejs如果要开启import的语法,需要在package.json里面加上这一句
基本输入输出和文件处理,输入输出流类的组织,这通常是比较繁琐的一部分,可以提纲挈领学一下,搞清楚概念,用到的时候查就是了。到这个阶段可以写大部分控制台应用了 nodejs 命令行输入
1 2 3 4 5 6 7 8 9 10 11 process.argv.forEach((val, index ) => { console .log(`${index} : ${val} ` ) })
Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。 Node 导入文件系统模块(fs)语法如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import * as fs from "fs" fs.readFile('input.txt' , function (err, data ) { if (err) { return console .error(err); } console .log("异步读取: " + data.toString()); }); let data = fs.readFileSync('input.txt' );console .log("同步读取: " + data.toString());console .log("程序执行完毕。" );fs.writeFile('input.txt' , '我是通 过fs.writeFile 写入文件的内容' , function (err ) { if (err) { return console .error(err); } console .log("数据写入成功!" ); });
该语言如何进行callback方法调用,如何支持事件驱动编程模型。在现代编程环境下,这个问题是涉及开发思想的一个核心问题,几乎每种语言在这里都会用足功夫,.NET的delegate,Java的anonymous inner class,Java 7的closure,C++OX的 tr1::function/bind,五花八门。如果能彻底理解这个问题,不但程序就不至于写得太走样,而且对该语言的设计思路也能有比较好的认识;
通过promise来avoid callback hell
1 2 3 4 5 6 7 8 9 10 11 12 import { readdir } from 'fs/promises' ;try { const files = await readdir(path); for (const file of files) console .log(file); } catch (err) { console .error(err); }
事件驱动模型,尽管Node.js 有多个内置的事件,但是如果想要自定义事件,那么可以使用EventEmitter
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 import * as events from "events" let eventEmitter = new events.EventEmitter(); let connectHandler = () => { console .log('连接成功。' ); eventEmitter.emit('data_received' ); } eventEmitter.on('connection' , connectHandler); eventEmitter.on('data_received' , function ( ) { console .log('数据接收成功。' ); }); eventEmitter.emit('connection' ); console .log("程序执行完毕。" );
如果有必要,可在这时研究regex和XML处理问题,如无必要可跳过;
序列化和反序列化,掌握一下缺省的机制就可以了; 1 2 3 4 5 6 7 8 9 10 11 12 13 class MyClass { constructor ( ) { this .foo = 3 } } let myClass = new MyClass()let json = JSON .stringify(myClass);let newMyClass = JSON .parse(json);
如果必要,可了解一下线程、并发和异步调用机制,主要是为了读懂别人的代码,如果自己要写这类代码,必须专门花时间严肃认真系统地学习,严禁半桶水上阵
动态编程,反射和元数据编程,数据和程序之间的相互转化机制,运行时编译和执行的机制,有抱负的开发者在这块可以多下些功夫,能够使你对语言的认识高出一个层面;
如果有必要,可研究一下该语言对于泛型的支持,不必花太多时间,只要能使用现成的泛型集合和泛型函数就可以了,可在以后闲暇时抽时间系统学习。需要注意的是,泛型技术跟多线程技术一样,用不好就成为万恶之源,必须系统学习,谨慎使用,否则不如不学不用;
如果还有时间,最好咨询一下有经验的人,看看这个语言较常用的特色features是什么,如果之前没学过,应当补一下。比如Ruby的block interator, Java的dynamic proxy,C# 3的LINQ和extension method。没时间的话,我认为也可以边做边学,没有大问题。
有必要的话,在工作的闲暇时间,可以着重考察两个问题,第一,这个语言有哪些惯用法和模式,第二,这个语言的编译/解释执行机制。