Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save xuanyuanaosheng/fbc3723f18ee463cbeec to your computer and use it in GitHub Desktop.
Save xuanyuanaosheng/fbc3723f18ee463cbeec to your computer and use it in GitHub Desktop.

#JavaScript第三次记录整理

作业地址传送门 ##一.数组

上次交流的时候,我们讨论过JS的两个基本类型,Number和String类型,分别表示数和字符串。

但是只有 Number 和 String 类型是不够的。表示更加复杂的类型则需要数组(Array)和对象(Object)。

先讲数组。一个数组类似于一个列表,可以储存多个JS的类型值。

比如 var items = ["a", "b", "c", 9];

这里存储了4个值,三个字符串和一个数。也就是说,数组允许我们将多个值存储在一个变量中。

是不是很方便呢?

一个数组的写法是方括号 [ ] 中,以逗号分隔多个值。

比如 [1, 2, 3, 4]

空的括号 [] 表示0个元素的数组。

items[0] 的语法就可以取得 items 中的第一个元素,按之前的例子, items[0] 是 "a"。

需要更改数组的话,则可以使用 items[0] = "aaa"; 这样的赋值语句。

也就是说,一个数组后面加上[0]基本上和一个变量的用法类似。

console.log 也支持输出数组如console.log([1,2,3]);

方括号中,必须是一个整数,或者是能计算成为整数值的表达式,如 items[1 + 1] 取第三个元素(不是第二个)。

当然也可以用变量,比如 var a = 1; var items = [2, 3]; console.log(items[a]); 结果应该是3。

再次说明,数组的类型是数组类型(Array),是不同于字符串和数的另一种基本类型。

数组的元素类型并没有限制的,比如 ["1", 2, [3, 4]] ,元素类型分别是字符串、数和数组

console.log([2,3]) 的输出由环境决定。NodeJS下可能是 [2,3]。开发者工具可能显示得更加友好,比如带有样式和高亮。

JS的数组大小是可以变化的,可以用 items.push(9); 在末尾增加一个元素,原先是 [1,2,3] 的会变成 [1,2,3,9]。

类似的还可以删除元素,如 items.pop(); 会去掉最后一个元素,变成 [1,2]

由于我们现在还没有学循环语句,所以没有办法对数组中的每个元素进行批量操作,只能手动用 items[0], items[1] 来操作,所以说暂时没太多用处。

##二.对象 对象也是JS的一种基本类型,其写法是 var obj = {a: 9};

这个可以理解成一个对象obj,其属性a为9。

怎么取得值呢?可以用 obj.a 也可以用 obj["a"]

注意如果用方括号获取的话,里面需要的是一个字符串,当然也可以是字符串表达式或者变量。

来自凤凰菊苣的插嘴 点操作符不能取带有短线的属性名,因为会被理解为运算符。

JS的对象相当于其他语言的字典dictionary或者map,可以认为是一个键值对。

比如说用于翻译的话, var dict = {"hello": "你好", "bye": "再见"}; 其中有两个元素,dict.hello 的值是 "你好", dict.bye 是 "再见"。

对象的键是允许任何字符串的,比如 {"a^@#sdfp": 9}。

如果碰巧那个字符串是合法的变量名,则可以省略引号,如 {a: 9} 与 {"a": 9} 等价。

在访问的时候,使用 obj["a"] 来获取。如果键碰巧是合法的名称,则可以使用 obj.a 这种简单的写法。

如果访问的键是不确定的,或者含有特殊字符,则只能使用 obj["a"] 这种语法来访问。

比如 var student={name: "Alice", score: 95};var prop="name";console.log(student[prop]);

这里利用一个字符串类型的变量来获取 student.name。

JS的对象类型和数组类型类似,也是复杂类型,区别就是对象类型用名字而不是序号。

student.name = "Bob"; 这样的语法可以用于更改对象的一个属性。

console.log 可以用于输出对象,至于输出什么大家自己试试看就好。

写对象的时候,冒号右侧可以是任意表达式,比如 var a = 9; var obj = {a: a}; 这里 a: 是表示键或者说属性名是 a, 而冒号右侧的 a 是取变量 a 的值。

有了数组和对象,就可以存一些比较复杂的内容了。

明显属于一个整体的两个值,比如一个学生的姓名和分数,可以考虑用对象来存储 var student={name: "Alice, score: 95};

如果用两个变量来存储,则传递和引用不太方便。

如何存储多个学生?太简单了: var students = [{name: "Alice", score: 95}, {name: "Bob", score: 80}];

这里首先是一个数组,这个数组的每一个元素是一个对象,分别有 name 和 score。

要取得第一个学生的姓名: students[0].name。

但是呢,如果我们想要取得 Alice 的姓名,就只能用循环一个个查找过去了。

如果需要根据名字,或者说根据字符串来查找,那么存储的时候最好选择用对象,比如 var scores = {"Alice": 9, "Bob": 10};

这样获取 Alice 的分数就是 scores["Alice"]。

所以刚才说过, JS 的对象可以当做字典或者map来用/

现在假设你来设计G+的社交圈。一个人有多个社交圈,每个圈子中有多个好友。请设计一个结构来存储某个人的好友列表。

下面再给出一种存储方式,仅供参考 var people = [{name: "AprocySanae", circles: ["菊苣", "土豪"]}, {name: "shizuko", circles: ["渣渣", "小透明"]}];

这种方式是保存每个人属于哪些圈子,而不是保存每个圈子有哪些人。

首先, var a = {}; 定义一个空对象。该对象没有任何用户定义的属性

那么空对象有什么用?一个用处是,对象是可以之后添加属性的。

给不存在的属性赋值则自动添加,比如 a.prop = 9; 会让 a 变成 {prop: 9}。

删除一个属性,则是 delete a.prop ,删除以后就和没存在过一样。

利用添加和删除,可以维护动态的圈子列表之类的。也可以把 JS 的对象当做集合用。

好了,到这里简单对象就基本介绍完毕了

##三.null和unidentified

我们再介绍两种 JS 的类型,分别是 null 和 undefined。

这两种类型的特殊之处在于只有一个值。 唯一的 null 类型值是 null, 而唯一的 undefined 类型值是 undefined。

要注意的是, null 是一个关键字,但 undefined 是一个全局变量。不排除有人恶意将 undefined 赋值成其他的值,要小心。

undefined 顾名思义,就是没有确定过的值。比如一个没有赋值过的变量。 var a; console.log(a); 这样输出是 undefined。

注意,如果没有 var a; 这句语句,那么会提示错误。一个没有值的变量和没有这个变量是不同的。

另一种说法是, JS 中所有变量的默认值是 undefined。访问不存在的属性,返回也是 undefined ,比如 var a = {}; console.log(a.prop);

不过返回 undefined 并不能判断一个属性不存在。可能那个属性存在,只是碰巧值是 undefined,比如 var a = {prop: undefined};

一个数组中不存在的元素也是 undefined,比如 var a = [1,2]; console.log(a[9999]);

undefined 也可以写作 void 0,不要问为什么。

至于每次 console.log(...) 出现的那个 undefined 嘛……函数如果没有返回值,那么其返回值默认为 undefined。

接下去讲一下 null。

null 表示空。已经有一个 undefined 了,为什么还需要一个 null? 谁知道呢。

只想到一种用途,需要表示一个空值,但又不能是 undefined 的情况下(比如说,可能和未定义的属性混淆起来?),可以用 null。

用 console.log(typeof 变量名) 可以看到一个变量的类型。

var a = 9; console.log(typeof a);

typeof 的运算结果总是字符串。

注意 typeof null 是 object 。这是一个意外……

顺便, typeof 一个不存在的变量名,结果是 "undefined"。

typeof 9 是 "number"。 typeof "abc" 是 "string"。

##四.boolean boolean 只有两个值, true 和 false ,表示真和假。

typeof true 是 "boolean",false当然也是。

JS 的相等判断有两种, == 和 ===。

1 === 1 结果是 true。

其中 === 判断类型相等且值相同,而 == 则试着把两边类型转换成一样的再判断是否相同。

资料 JavaScript等值表

! 是逻辑非,就是取相反。 !true 是 false, !false 是 true。

&& 是逻辑与, 两边都是 true ,结果为 true。否则为 false。

比如 1 + 1 === 2 && 1 + 2 === 3 是 true。

|| 是逻辑或,两个竖线。两边都是 false 结果为 false ,否则为 true。

注意数组和对象有自己的身份。任意两个数组的都是不相等的,比如 [] === [] 结果是 false。

只有自己和自己才相等,如 var a = []; console.log(a === a) 结果是 true。

{} === {} 会出现语法错误。只能写 ({}) === ({}) ,结果是 false。

无论长得再像的两个数组或者对象,都是不同的。就算console.log输出看不出区别,也不相等。

如果要判断两个数组的元素是否相等嘛……用循环……

判断一个数组是否为空,用的是 items.length === 0 来判断。

只有数组、对象、函数这三个复杂的类型有身份,其他的类型都被认为是简单类型,判断的都是值是否相等。

字符串是没有身份的,所以判断一个字符串是否为空可以是 a === "" 也可以是 a.length === 0。

身份这个说法,只是用于说明数组、对象、函数的特殊性。他们只和自己相等,和长得像的其他对象不相等。

所以我们称数组、对象、函数有”身份“,只是一种说法,避免每次都扯一长串定义。

对了补充一个坑, typeof [1,2] === "object",所以 typeof 不能区分数组和对象……坑。

事实上 typeof 的定义是就那么几种……对于不认识的,一概都是 "object"。

要判断一个变量 a 是不是数组,可以用 Array.isArray(a) 结果是 true 或者 false。

有身份的任何变量,都可以添加属性,比如数组、函数、对象都支持 a.prop = 9; 这种语法。

var x = {}; var y = x; 的时候, y 和 x 是同一个对象。

还有一个区别就是 {0:1, 1:2, 2:3} 其实是 {"0":1, "1":2, "2":3}。

然后对象不支持数组的各种操作,比如 push。

##五.控制语句

####条件语句

if (a === b) { console.log("相等"); } else { console.log("不相等") }

语法是 if (条件) { ...} else { ... } ,其中 else {...}可选,如果不写就是没有任何语句,条件时boolean的表达式。

boolean 以外转换成 boolean 。要记的只有空数组转换为 false, 空字符串转换为 false, 0 转换为 false, null 和 undefined 转换为 false 。其他都是 true。

记不住就不要记,用 === 之类的来严格判断。

条件成立执行第一个 { ... } ,不成立执行 else 后的那个 { ... }。

####循环语句

while (a < 10) { a += 1;}

空数组不是 false ,只是在 if 环境中会当做 false 处理。

循环语句语法是 while (条件) { ... } ,1. 检查条件成立,2. 如果成立执行 { ... },然后再回到第1步,如此反复。

while 的条件也是和 if 一样,可能存在转换。

for 循环是 while 循环的另一种写法。

语法是 for(A; B; C;) { D; } 相当于 A; for (A; B; C) { D; } ,但是 A, B, C 都只能是一个表达式,不能是多个语句。

常用的写法是 for (var i = 0; i < 10; i++) { console.log(i); } 输出 0 到 9。

但是有些时候 switch 语句什么的更方便,这些请自己学习啦。

关于 JS 的控制语句,如果不熟悉的话,请在 codecademy 自己练习吧~

需要讲的,只有 JS 特殊的语句而已。

首先是 for .. in

var a = {b: 3, d: 4}; for (var i in a) { console.log(i); }

这个会输出 "b" 和 "d"。

for (i in a) 的语法, 对于 a 的所有属性各执行一次,每一次 i 变成 a 的一个属性的名称,是一个字符串。

这样就可以 console.log(a[i]);。

对于长度为10的数组a, for (i in a) , i 依次变成 0, 1, 2, ... 9。

相当于 for (var i = 0; i < a.length; i++)

要注意的是, i 变成的是 0 到 a.length - 1,是变成数组的序号, 而不是像某些语言一样变成数组的值。

要拷贝一个数组,可以这样: var b = []; for (var i in a) { b.push(a[i]); }

如果直接 b = a; 那么 b 不是一个拷贝,而是和 a 共用一个数组,这个之前讲过。

#####Meeting ended at 15:02:20 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment