20200224 JavaScript【1】快速入门

2020.02.24-26为js入门学习期
参考 ①(主)廖雪峰教程 ②(辅)菜鸟教程


一 JS简介

JavaScript是世界上最流行的脚本语言,因为你在电脑、手机、平板上浏览的所有的网页,以及无数基于HTML5的手机App,交互逻辑都是由JavaScript驱动的。简单地说,JavaScript是一种运行在浏览器中的解释型的编程语言。在Web世界里,只有JavaScript能跨平台、跨浏览器驱动网页,与用户交互。随着HTML5在PC和移动端越来越流行,JavaScript变得更加重要了。并且,新兴的Node.js把JavaScript引入到了服务器端,JavaScript已经变成了全能型选手

廖佬的提醒:由于浏览器在发布时就确定了JavaScript的版本,加上很多用户还在使用IE6这种古老的浏览器,这就导致你在写JavaScript的时候,要照顾一下老用户,不能一上来就用最新的ES6标准写,否则,老用户的浏览器是无法运行新版本的JavaScript代码的。(不过,JavaScript的核心语法并没有多大变化。我们的教程会先讲JavaScript最核心的用法,然后,针对ES6讲解新增特性。)

二 光速入门

1、JS & HTML

JavaScript代码可以直接嵌在网页的任何地方,不过通常我们都把JavaScript代码放到head中

<html>
<head>
  <script>
    alert('Hello, world');
  </script>
</head>
<body>
  ...
</body>
</html>

script中包含的代码就是JavaScript代码,它将直接被浏览器执行。
以上是方法一

方法二: 使用.js文件
js的代码写在.js文件中,然后在HTML的head中通过一句话引入这个文件——

<html>
<head>
  <script src="/static/js/abc.js"></script>
</head>
<body>
  ...
</body>
</html>

这种做法更利于维护代码,并且多个页面可以各自引用同一份.js文件。

2、文本编辑器

★可以用任何文本编辑器来编写JavaScript代码,廖雪峰依旧推荐VScode!
注意:尽量不要用记事本编写JavaScript或HTML,它会自作聪明地在保存UTF-8格式文本时添加BOM头。

3、JS的注释

跟cpp一样!

// 以双斜杠开头直到行末的是注释,注释是给人看的,会被浏览器忽略
/* 从这里开始是块注释
仍然是注释
仍然是注释
注释结束 */

4、调试

①点击f12
②chrome的开发者工具打开

然后,点击“控制台(Console)“,在这个面板里可以直接输入JavaScript代码,按回车后执行。比如:要查看一个变量的内容,在Console中输入console.log(a); ,回车后显示的值就是变量的内容。在编写JavaScript代码时,经常需要在Console运行测试代码。

三 基础内容

1、语法

JavaScript的语法和Java语言类似,每个语句以;结束,语句块用{…}。

赋值语句:

var x = 1;

语句块是一组语句的集合,例如,下面的代码先做了一个判断,如果判断成立,将执行{…}中的所有语句:

if (2 > 1) {
    x = 1;
    y = 2;
    z = 3;
}

语句具有缩进,通常是4个空格。但缩进不是JavaScript语法要求必须的!
{…}还可以嵌套,形成层级结构: //跟C几乎一样…

if (2 > 1) {
    x = 1;
    y = 2;
    z = 3;
    if (x < y) {
        z = 4;
    }
    if (x > y) {
        z = 5;
    }
}

注意:过多的嵌套无疑会大大增加看懂代码的难度。遇到这种情况,需要把部分代码抽出来,作为函数来调用,这样可以减少代码的复杂度

提醒:
JavaScript严格区分大小写,如果弄错了大小写,程序将报错或者运行不正常!

2、数据类型

计算机能处理的数据远不止数值,它还可以处理文本、图形、音频、视频、网页等各种各样的数据,不同的数据,需要定义不同的数据类型。在JavaScript中定义了以下几种数据类型:

  1. Number
    JavaScript不区分整数和浮点数,统一用Number表示。
    特别记下:
    ①NaN——无法计算结果(Not a Number)
    ②Infinity——无穷大(当数值超过了JavaScript的Number所能表示的最大值时)
1 + 2; // 3
(1 + 2) * 5 / 2; // 7.5
2 / 0; // Infinity
0 / 0; // NaN
10 % 3; // 1  (%是求余运算)
10.5 % 3; // 1.5
  1. 字符串
    字符串是以单引号’或双引号"括起来的任意文本(类似python)。
    如果’本身也是一个字符,那就可以用"“括起来,比如"I’m OK” 。

★如果字符串内部既包含’又包含"怎么办?可以用转义字符“\”来标识,比如:
(好像就是和python一样一样的…)

'I\'m \"OK\"!';  //输出:I'm "OK"!

★转义字符:

\n表示换行,\t表示制表符,字符\本身也要转义,所以\表示的字符就是\ 。

★多行字符串的写法举例:【“ ` ”是英文输入时,esc下面的那个按键!】

console.log(`多行
字符串
测试`); //输出分为三行显示!

★模板字符串
要把多个字符串连接起来,可以用+号连接

var name = '小明';
var age = 20;
var message = '你好, ' + name + ', 你今年' + age + '岁了!';
alert(message);

output:你好, 小明, 你今年20岁了!

★字符串的常见操作
①求长度

var s = 'Hello, world!';
s.length; // 13

②要获取字符串某个指定位置的字符,使用类似Array的下标操作:
(索引从0开始)

var s = 'Hello, world!';

s[0]; // 'H'
s[6]; // ' '
s[7]; // 'w'
s[12]; // '!'
s[13]; // undefined 超出范围的索引不会报错,但一律返回undefined

字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果!例如:

var s = 'Test';
s[0] = 'X';
alert(s); // s仍然为'Test'

注意:js为字符串提供了一些常用方法(下面介绍的都是),调用这些方法本身不会改变原有字符串的内容,而是返回一个新字符串~

④toUpperCase( ) 【全都变大写】

var s = 'Hello';
s.toUpperCase(); // 返回'HELLO'

⑤toLowerCase( )【全都变小写】

var s = 'Hello';
var lower = s.toLowerCase(); // 返回'hello'并赋值给变量lower
lower; // 'hello'

⑥indexOf( ) 【搜索指定字符串出现的位置】

var s = 'hello, world';
s.indexOf('world'); // 返回7
s.indexOf('World'); // 没有找到指定的子串,返回-1

⑦substring( ) 【返回指定索引区间的子串】

var s = 'hello, world'
s.substring(0, 5); // 从索引0开始到5(不包括5),返回'hello'
s.substring(7); // 从索引7开始到结束,返回'world'
  1. 布尔值
    布尔值和布尔代数的表示完全一致,一个布尔值只有true、false两种值
    相关补充:

&& 运算是与运算
|| 运算是或运算
! 运算是非运算

布尔值经常用在条件判断中(if语句)。
另外,比较运算符同cpp。

★ 实际上,JavaScript允许对任意数据类型做比较:

false == 0; // true
false === 0; // false

js有两种比较运算符——

①第一种是==比较
它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果(上面的代码)

②第二种是===比较 【始终坚持使用这个方式
它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。

上面这坨概括起来就是:js中的等号是三个等号。

  1. null和undefined
    null表示一个“空”的值,它和0以及空字符串’ '不同。
    而undefined表示值未定义。
    大多数情况下,我们都应该用null。undefined仅仅在判断函数参数是否传递的情况下有用。

  2. 数组
    数组是一组按顺序排列的集合,集合的每个值称为元素。JavaScript的数组可以包括任意数据类型。例如:[1, 2, 3.14, ‘Hello’, null, true];
    数组的元素可以通过索引来访问。请注意,索引的起始值为0

var arr = [1, 2, 3.14, 'Hello', null, true];
arr[0]; // 返回索引为0的元素,即1
arr[5]; // 返回索引为5的元素,即true
arr[6]; // 索引超出了范围,返回undefined

Array可以通过索引把对应的元素修改为新的值,因此,对Array的索引进行赋值会直接修改这个Array:(如果通过索引赋值时,索引超过了范围,会引起Array大小的变化,越界访问索引不会报错! )

var arr = ['A', 'B', 'C'];
arr[1] = 99;
arr[5] = 'x';
arr; // arr现在变为['A', 99, 'C',undefined, 'x']

★ indexOf( )返回索引值
看例子就懂了——

var arr = [10, 20, '30', 'xyz'];
arr.indexOf(10); // 元素10的索引为0
arr.indexOf(20); // 元素20的索引为1
arr.indexOf(30); // 元素30没有找到,返回-1
arr.indexOf('30'); // 元素'30'的索引为2

★ slice( )截取部分元素并返回一个新的array
看例子就懂了——

var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 从索引3开始到结束: ['D', 'E', 'F', 'G']

(0,3)潜在含义:左闭右开区间 !

★ push和pop 【尾部操作】
push()向Array的末尾添加若干元素,pop()则把Array的最后一个元素删除掉!
看例子就懂——

var arr = [1, 2];
arr.push('A', 'B'); // 返回Array新的长度: 4
arr; // [1, 2, 'A', 'B']
arr.pop(); // pop()返回'B'
arr; // [1, 2, 'A']
arr.pop(); arr.pop(); arr.pop(); // 连续pop 3次
arr; // []
arr.pop(); // 空数组继续pop不会报错,而是返回undefined
arr; // []

★ unshift和shift 【头部操作】
如果要往Array的头部添加若干元素,使用unshift()方法,shift()方法则把Array的第一个元素删掉!
看例子吧——

var arr = [1, 2];
arr.unshift('A', 'B'); // 返回Array新的长度: 4
arr; // ['A', 'B', 1, 2]
arr.shift(); // 'A'
arr; // ['B', 1, 2]
arr.shift(); arr.shift(); arr.shift(); // 连续shift 3次
arr; // []
arr.shift(); // 空数组继续shift不会报错,而是返回undefined
arr; // []

★ sort( ) 排序
(直接调用时,按照默认顺序排序)

var arr = ['B', 'C', 'A'];
arr.sort();
arr; // ['A', 'B', 'C']

★ reverse 数组反向

var arr = ['one', 'two', 'three'];
arr.reverse(); 
arr; // ['three', 'two', 'one']

★★ 万能的 splice( ) —— 修改操作会这个就够!

var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']

★ concat( ) 连接两个数组

var arr = ['A', 'B', 'C'];
var haha = arr.concat([1, 2],3); //concat还可以接收到数组
haha; // ['A', 'B', 'C', 1, 2, 3]
arr; // ['A', 'B', 'C']

★ join( )
P.S. 听说很实用,但小白实在看不懂实用在哪…廖佬说是就是吧…
join( )把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串——

var arr = ['A', 'B', 'C', 1, 2, 3]; //如果Array的元素不是字符串,将自动转换为字符串后再连接。
arr.join('-'); // 'A-B-C-1-2-3'

★多维数组
如果数组的某个元素又是一个Array,则可以形成多维数组,例如:
var arr = [[1, 2, 3], [400, 500, 600], ‘-’];
上述Array包含3个元素,其中头两个元素本身也是Array。

  1. 对象 (类似C的结构体!)
    JavaScript的对象是一组由 键-值 组成的无序集合,例如:
var person = {
    name: 'Bob', //注意:是逗号!!!
    age: 20,
    tags: ['js', 'web', 'mobile'],
    city: 'Beijing',
    hasCar: true,
    zipcode: null  //警告:最后一个属性不必加逗号了不然可能报错!!
};

JavaScript对象的键都是字符串类型,值可以是任意数据类型。上述person对象一共定义了6个键值对,其中每个键又称为对象的属性,例如,person的name属性为’Bob’,zipcode属性为null。

要获取一个对象的属性,我们用 对象变量.属性名 的方式:

person.name; // 'Bob'
person.zipcode; // null

【骚】由于JavaScript的对象是动态类型,你可以自由地给一个对象添加或删除属性: (看完就懂系列——)

var xiaoming = {
    name: '小明'
};
xiaoming.age; // undefined
xiaoming.age = 18; // 新增一个age属性
xiaoming.age; // 18
delete xiaoming.age; // 删除age属性
xiaoming.age; // undefined

3、变量

变量名的起名方式同其他语言。
申明一个变量用var语句,比如:

var a; // 申明了变量a,此时a的值为undefined
var $b = 1; // 申明了变量$b,同时给$b赋值,此时$b的值为1
var s_007 = '007'; // s_007是一个字符串
var Answer = true; // Answer是一个布尔值true
var t = null; // t的值是null

可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量但是要注意只能用var申明一次,例如:

var a = 123; // a的值是整数123
a = 'ABC'; // a变为字符串

这种变量本身类型不固定的语言称之为动态语言

补充:
静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。例如Java是静态语言。

输出:要显示变量的内容,可以用console.log(x),打开Chrome的控制台就可以看到结果。使用console.log()代替alert()的好处是可以避免弹出烦人的对话框

4、strict模式 (严格模式)

在JavaScript代码的第一行写上该代码即可开启strict模式:

'use strict';

写这句话的用处——
在没用var定义变量时,系统会报错。

定义变量时一定要var来申明,否则会造成全局变量的产生!如:

i = 10; // i现在是全局变量

在同一个页面的不同的JavaScript文件中,如果都不用var申明,恰好都使用了变量i,将造成变量i互相影响,产生难以调试的错误结果。而使用var申明的变量则不是全局变量,它的范围被限制在该变量被申明的函数体内,同名变量在不同的函数体内互不冲突。

5、条件判断 (if…else…)

操作和c语言一模一样!另外,建议永远都要写上{ }。

也可以 if…else if …else{ }

6、循环(主要是2种)

No.1 for循环

var x = 0;
var i;
for (i=1; i<=10000; i++) //和c一样的!
{
    x += i;  //也是可以这样写的!
}
x; // 50005000

for循环的3个条件都是可以省略的,如果没有退出循环的判断条件,就必须使用break语句退出循环。

★另一重要例子——

'use strict';
var arr = ['Bart', 'Lisa', 'Adam'];
var i;

for(i=0;i<arr.length;i++){
    console.log(`hello, ${arr[i]}!`) //注意看这句话怎么写的!!!!!
};

output
hello, Bart!
hello, Lisa!
hello, Adam!

No.2 for…in循环
for循环的一个变体。它可以把一个对象的所有属性依次循环出来:
(和python一样)看完就懂了——

var o = {
    name: 'Jack',
    age: 20,
    city: 'Beijing'
};
for (var key in o) {    /*注意for里面的写法*/
    console.log(key); // 'name', 'age', 'city'
}

No.3 while循环
跟c语言一模一样~~看例子吧:

var x = 0;
var n = 99;
while (n > 0) {
    x = x + n;
    n = n - 2;
}
x; // 2500

No.4 do…while循环

var n = 0;
do {
    n = n + 1;
} while (n < 100);
n; // 100

注意:用do { … } while( )循环要小心,循环体会至少执行1次,而for和while循环则可能一次都不执行!

7、Map

Map是一组键值对的结构,具有极快的查找速度。

给定一个名字,要查找对应的成绩:只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用JavaScript写一个Map如下:

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95

初始化Map需要一个二维数组,或者直接初始化一个空Map。Map具有以下方法:

var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.set('Bob', 62);// 会刷新掉上一行记录的59~
m.get('Bob'); // 62
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined

8、Set 集合

Set和Map类似,也是一组key的集合,但不存储value
在Set中,没有重复的key!

要创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set:

var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3

提醒:重复元素在Set中自动被过滤!!
look——
var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}

通过add(key)方法可以添加元素到Set中,可以重复添加,但不会有效果:

s.add(4);
s; // Set {1, 2, 3, 4}
s.add(4);
s; // 仍然是 Set {1, 2, 3, 4}

通过delete(key)方法可以删除元素。

9、iterable (可迭代的)

遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。具有iterable类型的集合可以通过新的for … of循环来遍历

用for … of循环遍历集合,用法如下:

var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
    console.log(x);
}
for (var x of s) { // 遍历Set
    console.log(x);
}
for (var x of m) { // 遍历Map
    console.log(x[0] + '=' + x[1]);
}

★for … of循环和for … in循环有何区别?

for … in循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。当我们手动给Array对象添加了额外的属性后,for … in循环将带来意想不到的意外效果:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
    console.log(x); // '0', '1', '2', 'name'
}

for … in循环将把name包括在内,但Array的length属性却不包括在内。for … of循环则完全修复了这些问题,它只循环集合本身的元素:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a) {
    console.log(x); // 'A', 'B', 'C'
}

对比以上两个代码段!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章