JavaScript摘要

JavaScript摘要

1.基本数据类型

JavaScript的基本构建块包括:对象(object)、原语(primitive)和字面量(literal)。

literal 表示特定类型的一个值,例如:String, Number, or Boolean。

1
2
3
"this is a string"
1.45
true

Primitive 是一个特定数据类型的实例,包括五种:String, Number, Boolean, null, undefined。

JavaScript 的世界中,一切皆对象(object)。

2.基本语法

函数声明:

1
2
3
4
5
function distance(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt(dx*dx + dy*dy);
}

条件语句:

1
2
3
4
5
6
7
if (x <= 1){ 
return 1;
}else{
return x*fact(x-1);
}

if (this.length == 0) return this;

循环语句:

1
2
3
4
5
6
7
8
9
10
11
for(i=0;i<10;i++){
tst+=i;
}

for (var i in obj) {
result += obj_name + "." + i + " = " + obj[i] + "<br>";
}

while((matchArray = pattern.exec(searchString)) != null) {
str+="at " + matchArray.index + " we found " + matchArray[0] + "\n";
}

3.数组

创建数组:

1
2
3
var arr = new Array(element0, element1, ..., elementN);
var arr = Array(element0, element1, ..., elementN);
var arr = [element0, element1, ..., elementN];

填充数组:

1
2
3
4
5
6
7
8
var emp = [];
emp[0] = "Casey Jones";
emp[1] = "Phil Lesh";
emp[2] = "August West";
var arr = [];
arr[3.4] = "Oranges";
console.log(arr.length); // 0
console.log(arr.hasOwnProperty(3.4)); // true

如果你在以上代码中给数组操作符的是一个非整形数值,那么将作为一个代表数组的对象的属性(property)创建,而非作为数组的元素。

引用数组元素:

1
2
3
var arr = ["one", "two", "three"];
arr[2]; // three
arr["length"]; // 3

数组操作符(方括号 [ ])也可以用来访问数组的属性(在 JavaScript 中,数组也是对象)。

遍历数组:

1
2
3
4
5
6
7
8
9
var colors = ['red', 'green', 'blue'];
for (var i = 0; i < colors.length; i++) {
console.log(colors[i]);
}

var colors = ['red', 'green', 'blue'];
colors.forEach(function(color) {
console.log(color);
});

数组对象的方法:

concat() 连接两个数组并返回一个新的数组。

join(deliminator = ',') 将数组的所有元素连接成一个字符串。

push() 在数组末尾添加一个或多个元素,并返回数组操作后的长度。

pop() 从数组移出最后一个元素,并返回该元素。

shift() 从数组移出第一个元素,并返回该元素。

4.集合类

Map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
sayings.set('elephant', 'toot');
sayings.size; // 3
sayings.get('fox'); // undefined
sayings.has('bird'); // false
sayings.delete('dog');
sayings.has('dog'); // false

for (var [key, value] of sayings) {
console.log(key + ' goes ' + value);
}
// "cat goes meow"
// "elephant goes toot"

sayings.clear();
sayings.size; // 0

Map和Object的比较:

一般地,objects会被用于将字符串类型映射到数值。Object允许设置键值对、根据键获取值、删除键、检测某个键是否存在。而Map具有更多的优势。

  • Object的键均为Strings类型,在Map里键可以是任意类型。
  • 必须手动计算Object的尺寸,但是可以很容易地获取使用Map的尺寸。
  • Map的遍历遵循元素的插入顺序。
  • Object有原型,所以映射中有一些缺省的键。(可以理解为map = Object.create(null))。

Set

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var mySet = new Set();
mySet.add(1);
mySet.add("some text");
mySet.add("foo");

mySet.has(1); // true
mySet.delete("foo");
mySet.size; // 2

for (let item of mySet) console.log(item);
// 1
// "some text"
# Array 和 Set的转换
Array.from(mySet);
[...mySet2];

mySet2 = new Set([1,2,3,4]);

Array和Set的对比:

一般情况下,在JavaScript中使用数组来存储一组元素,而新的集合对象有这些优势:

  • 数组中用于判断元素是否存在的indexOf 函数效率低下。
  • Set对象允许根据值删除元素,而数组中必须使用基于下标的 splice 方法。
  • 数组的indexOf方法无法找到NaN值。
  • Set对象存储不重复的值,所以不需要手动处理包含重复值的情况。

5.字符串

String 字面量

1
2
'foo'
"bar"

String对象

String对象是对 String 类型的封装。

1
2
3
var s = new String("foo"); // Creates a String object
console.log(s); // Displays: { '0': 'f', '1': 'o', '2': 'o'}
typeof s; // Returns 'object'

模板字符串

1
2
3
4
5
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."
方法 描述
charAt, charCodeAt, codePointAt 返回字符串指定位置的字符或者字符编码。
indexOf, lastIndexOf 分别返回字符串中指定子串的位置或最后位置。
startsWith, endsWith, includes 返回字符串是否以指定字符串开始、结束或包含指定字符串。
concat 连接两个字符串并返回新的字符串。
fromCharCode, fromCodePoint 从指定的Unicode值序列构造一个字符串。这是一个String类方法,不是实例方法。
split 通过将字符串分离成一个个子串来把一个String对象分裂到一个字符串数组中。
slice 从一个字符串提取片段并作为新字符串返回。
substring, substr 分别通过指定起始和结束位置,起始位置和长度来返回字符串的指定子集。

6.面向对象

基于类VS基于原型的语言

基于类的面向对象语言,比如 Java 和 C++,是构建在两个不同实体的概念之上的:即类和实例。

  • 类可以定义属性,这些属性可使特定的对象集合特征化(可以将 Java 中的方法和变量以及 C++ 中的成员都视作属性)。类是抽象的,而不是其所描述的对象集合中的任何特定的个体。例如 Employee 类可以用来表示所有雇员的集合。
  • 另一方面,一个实例是一个类的实例化;也就是其中一名成员。例如, Victoria 可以是 Employee 类的一个实例,表示一个特定的雇员个体。实例具有和其父类完全一致的属性。

基于原型的语言(如 JavaScript)并不存在这种区别:它只有对象。基于原型的语言具有所谓原型对象的概念。原型对象可以作为一个模板,新对象可以从中获得原始的属性。任何对象都可以指定其自身的属性,既可以是创建时也可以在运行时创建。而且,任何对象都可以作为另一个对象的原型,从而允许后者共享前者的属性。

差异总结

基于类的(Java) 基于原型的(JavaScript)
类和实例是不同的事物。 所有对象均为实例。
通过类定义来定义类;通过构造器方法来实例化类。 通过构造器函数来定义和创建一组对象。
通过 new 操作符创建单个对象。 相同。
通过类定义来定义现存类的子类,从而构建对象的层级结构。 指定一个对象作为原型并且与构造函数一起构建对象的层级结构
遵循类链继承属性。 遵循原型链继承属性。
类定义指定类的所有实例的所有属性。无法在运行时动态添加属性。 构造器函数或原型指定初始的属性集。允许动态地向单个的对象或者整个对象集中添加或移除属性。
  1. 首先了解该语言的基本数据类型,基本语法和主要语言构造,主要数学运算符和print函数的使用,达到能够写谭浩强程序设计书课后数学习题的程度;
  2. 其次掌握数组和其他集合类的使用,有基础的话可以理解一下泛型,如果理解不了也问题不大,后面可以补;
  3. 简单字符串处理。所谓简单,就是Regex和Parser以下的内容,什么查找替换,截断去字串之类的。不过这个阶段有一个难点,就是字符编码问题。如果理解不了,可以先跳过,否则的话最好在这时候把这个问题搞定,免留后患;
  4. 基本面向对象或者函数式编程的特征,无非是什么继承、多态、Lambda函数之类的,如果有经验的话很快就明白了;
  5. 异常、错误处理、断言、日志和调试支持,对单元测试的支持。你不一定要用TDD,但是在这个时候应该掌握在这个语言里做TDD的基本技能;
  6. 程序代码和可执行代码的组织机制,运行时模块加载、符号查找机制,这是初学时的一个难点,因为大部分书都不太注意介绍这个极为重要的内容;
  7. 基本输入输出和文件处理,输入输出流类的组织,这通常是比较繁琐的一部分,可以提纲挈领学一下,搞清楚概念,用到的时候查就是了。到这个阶段可以写大部分控制台应用了;
  8. 该语言如何进行callback方法调用,如何支持事件驱动编程模型。在现代编程环境下,这个问题是涉及开发思想的一个核心问题,几乎每种语言在这里都会用足功夫,.NET的delegate,Java的anonymous inner class,Java 7的closure,C++OX的 tr1::function/bind,五花八门。如果能彻底理解这个问题,不但程序就不至于写得太走样,而且对该语言的设计思路也能有比较好的认识;
  9. 如果有必要,可在这时研究regex和XML处理问题,如无必要可跳过;
  10. 序列化和反序列化,掌握一下缺省的机制就可以了;
  11. 如果必要,可了解一下线程、并发和异步调用机制,主要是为了读懂别人的代码,如果自己要写这类代码,必须专门花时间严肃认真系统地学习,严禁半桶水上阵;
  12. 动态编程,反射和元数据编程,数据和程序之间的相互转化机制,运行时编译和执行的机制,有抱负的开发者在这块可以多下些功夫,能够使你对语言的认识高出一个层面;
  13. 如果有必要,可研究一下该语言对于泛型的支持,不必花太多时间,只要能使用现成的泛型集合和泛型函数就可以了,可在以后闲暇时抽时间系统学习。需要注意的是,泛型技术跟多线程技术一样,用不好就成为万恶之源,必须系统学习,谨慎使用,否则不如不学不用;
  14. 如果还有时间,最好咨询一下有经验的人,看看这个语言较常用的特色features是什么,如果之前没学过,应当补一下。比如Ruby的block interator, Java的dynamic proxy,C# 3的LINQ和extension method。没时间的话,我认为也可以边做边学,没有大问题。
  15. 有必要的话,在工作的闲暇时间,可以着重考察两个问题,第一,这个语言有哪些惯用法和模式,第二,这个语言的编译/解释执行机制。

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×