JS 学习笔记

本篇文章为作者在网上自学JS时的笔记,看的狂神的b站视频
视频链接

概述

本人认为JS的语法和Java,python及其相似,像是融合了这两种语言的语法

快速引入

引入JavaScript

内部标签

1
2
3
<script> 
\\\ js代码
</script>

外部标签

1
<script src = "xxx.js"></script>

基本语法

1
2
3
4
5
6
7

// 变量的类型可以任意
var num = 1;
var name = "mcola";
var float = 1.1;

// 注意变量名不能以数字开头,但是可以用中文命名

输出

1
2
3
alert(xxx); // 在页面弹窗输出内容

console.log(xxx); // 在页面的控制台(F12)输出内容

数据类型

比较运算符

1
2
3
4
5
6
7
= 
== //等于(类型不一样,值相同也为true)
=== // 绝对等于(要求类型和值均相同才为true)

------------------------
NaN === NaN // 为false,NaN与任何值都不相同包括它自己
// 只能通过isNaN(NaN)来判断

数组

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
var array = [1,2,3,1.1,"mcola"];

// 改变数组长度则数组的空间也会变化
array.length = 10;
// 则array就会变为有10个元素的数组,后面的元素为空
array.length = 2;
// 则只有索引为0和1的元素,其他元素丢失

// 根据元素获取下标
array.indexOf(1.1) // 则会输出3

// slice()
arr.slice(3); // 从下标3开始往后截,生成一个新的数组

// push()
arr.push('a'); // 在数组最后添加

// pop()
arr.pop(); // 输出数组最后一个元素,并删除这个元素

// unshift();
arr.unshift('a'); // 在头部插入一个元素

// shift();
arr.shift(); // 弹出头部的元素

// sort();
arr.sort(); // 排序

// reverse();
arr.reverse(); // 数组反转

// concat();
arr.concat([1,2,3]); // 添加一个新的数组在尾部,但是不改变原来的数组

// join();
arr.join('-'); // 打印数组,使用特定的拼接符链接

// 多维数组
arr = [[1,2],[3,4]] // 与c++一样

取数组下标,如果越界了就会显示undefined(未定义),而不是null(空)

对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 定义一个对象
var person = {
name:"mcola", // 使用逗号分隔不同属性
age:20,
school:ZJUT;
}

// 取对象的值,直接在控制台输入即可输出
person.name
person.age

// 动态删除属性
delete person.age;

// 动态添加属性
person.hobby = "playing"; // 只要对一个没定义的属性赋值就会添加这个属性

// 判断属性值是否在对象中
'age' in person // 输出为true则在
// 但是这包括了继承的属性

// 判断属性值是否是这个对象自身拥有的
person.hasOwnProperty('age');

严格检查机制

1
2
'use strict' // 在script代码最开始写上这个
let num = 1; // 后面都这样定义变量

字符串

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
// 转义字符
/'
/t
/n

// 输入多行字符串

var msg = `
hello
world
`

// 模板字符串
let name = "mcola";
let msg = `hello , ${name}` // 输出hello , mcola

// 字符串长度
string.length

// 字符串的不可变性
var str = "hello"; // 不能通过str[0]='a'来修改字符串

// 字符串的一些方法
// 大小写转换
student.toUpperCase()
student.toLowerCase()

// 获取某个元素的下标
student.indexOf('t') // 在student字符串中t元素所在的下标

// substring
[) // 前闭后开
student.substring(1) // 从索引为1的字符截取到最后
student.substring(1,3) // 总索引为1的字符截取到索引为3(不包括3)的字符

Map

1
2
3
4
5
var map = new Map([["tom",100],["jack",90]]);
var score = map.get("tom"); // 通过key获得value

map.set("mcola",123); // 添加元素
map.delete("tom"); // 删除

Set

1
2
3
4
5
// 无序不重复集合
var set = new Set([1,2,3,3]); // 输出为1,2,3 ,自动去重
set.add(4); // 添加元素
set.delete(3); // 删除元素
set.has(1); // 判断是否包含

iterator遍历Map和Set

1
2
3
4
5
6
7
8
9
var map = new Map([["tom",100],["jack",90]]);
for (let x of map){
console.log(x);
}

var set = new Set([1,2,3,3]);
for (let x of set){
console.log(x);
}

流程控制

if判断

1
2
3
4
5
6
// 与其他语言一样
if(num>12){
xxx
}else {
xxx
}

while循环

1
2
3
4
5
6
7
8
9
10
// 与其他语言一样
while(n<m){
console.log(n);
n++;
}

do{
console.log(n);
n++;
}while(n<m)

for循环

1
2
3
for (let i=0;i<10;i++){
console.log(i);
}

数组循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var array = [1,2,3,1.2,"mcola"];

for(var i in array){
console.log(array(i); // 输出数组中的每一个元素,i为索引
}

// 注意区分
------------------------
for(var i of array){
console.log(i); // 输出数组中的每一个元素,i为元素
}

// forEach循环
array.forEach(function(value){
cosole.log(value);
})

函数

定义方式一(建议)

1
2
3
4
5
function abs(x){
if(x>=0){
return x;
}else return -x;
}

定义方式二

1
2
3
4
5
var abs = function(x){
if(x>=0){
return x;
}else return -x;
}

调用函数

1
abs(10);

参数问题

可以传递任意个参数,也可以不传递参数

‘arguments’ 代表传进来的所有参数是一个数组,可以拿出来所有传入的参数

Rest

1
2
3
function add(a,b,...rest){
console.log(rest); // 将剩下未定义的参数全部放到一个数组中
}

规避参数异常

1
2
3
if(typeof x !== number){
throw 'Not a number';
}

变量的作用域

在函数体内用var定义的变量在函数体外是不能用的(闭包)

1
2
3
4
5
6
7
8
'use strict';
function f() {
var x = 1;
}
x = x + 1; // Uncaught ReferenceError: x is not defined

---------------------------------------

内部函数可以访问外部函数的变量,反之不行

1
2
3
4
5
6
7
8
'use strict';
function f() {
var x = 1;
function f2(){
var y = x + 1;// 2
}
var z = x + y; // 报错
}

调用函数从内向外,内部屏蔽外部函数的同名变量

1
2
3
4
5
6
7
8
9
function f() { 
var x = 1;
function f2(){
var x = 'a';
console.log(x); // a
}
console.log(x); // 1
f2();
}

JS自动提升了变量的声明,但是不会提升赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
function f() { 
var x = '1'+y;
console.log(x); // 1undefined
var y = 2;
}

// 这两个函数是等价的
function f2(){
var y;
var x = '1'+y;
console.log(x);
y = 2;
}

规范:把所有变量的定义全部放在最前面

1
2
3
4
5
6
 function f() { 
var x = 1,
y = x + 1,
z,m;
// ...
}

全局变量:定义在函数外部

默认所有全局变量会自动绑定在window对象下,为了减少重名的冲突,把自己的代码全部放入自己定义的唯一空间名中(jQuery)

1
2
3
4
5
6
7
var x = 1;
function f(){
console.log(x);
}
console.log(window.x); // 等价
alert(x);
window.alert(x); // alert也是绑定在window对象下的

局部作用域:let

1
2
3
4
5
6
function f() { 
for (var i = 0; i < 5; i++) {
console.log(i);
}
console.log(i+1); // 能够在循环体外面使用i
}

使用let可以解决这个问题,建议使用let定义局部作用域

1
2
3
4
5
6
function f() { 
for (let i = 0; i < 5; i++) {
console.log(i);
}
console.log(i+1); // 能够在循环体外面使用i
}

常量 const

在ES6之前,约定全部大写的变量为常量,但是任然可以改变

1
2
var PI = 3.14;
PI = 213;

在ES6引入const,这样强制规定不能改变变量

方法

定义方式

把函数放在对象里

1
2
3
4
5
6
7
8
9
10
11
12
13
var person = {
name: mcola,
birth: 2003,
age: function(){
var now = new Date().getFullYear();
return now-this.birth;
}
}

// 调用属性
person.name
// 调用方法
person.age()