一、什么是 JavaScript

1.概述

JavaScript 是一门世界上最流行的脚本语言(相当于浏览器解释)

一个合格的后端人员必须要精通 JavaScript

ECMAScript : 往往被称为 JavaScript 或 Jscript ,它可以理解为是 JavaScript的一个标准

最新版本已经到 ES 6 版本,但是大部分浏览器还只停留在支持 ES 5 代码上,这就导致 开发环境 - 线上环境,版本不一致

2.历史

JavaScript的起源故事_javascript历史

网景是网景通信公司(Netscape Communications Corporation)的常用简称。网景通信公司曾经是一家美国的计算机服务公司,以其生产的同名网页浏览器[Netscape Navigator](https://baike.baidu.com/item/Netscape Navigator/1014148)而闻名(正是因为这个浏览器才有了 JavaScript)。

“1994年,网景公司(Netscape)发布了Navigator浏览器0.9版。这是历史上第一个比较成熟的网络浏览器,轰动一时。但是,这个版本的浏览器只能用来浏览,不具备与访问者互动的能力。…网景公司急需一种网页脚本语言,使得浏览器可以与网页互动。

总之,当时的形势就是,网景公司的整个管理层,都是Java语言的信徒,Sun公司完全介入网页脚本语言的决策。

此时,34岁的系统程序员Brendan Eich登场了。1995年4月,网景公司录用了他。

Brendan Eich的主要方向和兴趣是函数式编程(JavaScript 里面大量运用的东西),网景公司招聘他的目的,是研究将Scheme语言作为网页脚本语言的可能性。Brendan Eich本人也是这样想的,以为进入新公司后,会主要与Scheme语言打交道。

仅仅一个月之后,**1995年5月,网景公司做出决策,未来的网页脚本语言必须"看上去与Java足够相似",但是比Java简单,使得非专业的网页作者也能很快上手。**这个决策实际上将Perl、Python、Tcl、Scheme等非面向对象编程的语言都排除在外了。

Brendan Eich被指定为这种"简化版Java语言"的设计师。

但是,他对Java一点兴趣也没有。为了应付公司安排的任务,他只用10天时间就把Javascript设计出来了。

由于设计时间太短,语言的一些细节考虑得不够严谨,导致后来很长一段时间,Javascript写出来的程序混乱不堪。如果Brendan Eich预见到,未来这种语言会成为互联网第一大语言,全世界有几百万学习者,他会不会多花一点时间呢?

多年以后,Brendan Eich还是看不起Java。

二、快速入门

1.引入 JavaScript

1.内部标签

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>快速入门</title><!-- script 标签内,写 JavaScript 代码,可以放在任何地方,一般放在 body 标签最下面或者 head 标签里面--><script>alert('快速入门');</script></head>
<body></body>
</html>

2.外部引入

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>快速入门</title><!--引入外部 JavaScript 文件--><!--注意:script 标签必须成对出现--><script src="js/MyScript.js"></script><!--不用显式定义 type ,默认就是 text/javascript --><script type="text/javascript"></script>
</head>
<body></body>
</html>

MyScript.js

alert('外部引用');

2.基本语法入门

修改JavaScript语言版本

默认 ECMAScript 5.1,写的时候修改成 ECMAScript 6,这样的话语法更严谨

基本语法入门

  • EsLink 帮助我们检查Javascript编程时的语法错误。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>基本语法入门</title><!--JavaScript 严格区分大小写!--><script>//1. 定义变量  //变量类型 变量名 = 变量值;//一切的变量类型都叫 var//JavaScript 可以不写 ; 结尾,但是编译打包的时候,会把多行变为一行var score = 1;  //数值var str = "字符串";  //字符串//2.条件控制if (score > 60 && score < 70) {console.log("60 ~ 70");  //在浏览器的控制台打印变量} else if (score > 70 && score < 80) {console.log("70 ~ 80");} else {console.log("other");}</script>
</head>
<body></body>
</html>

浏览器控制台使用

元素(Elements):HTML 和 CSS(爬网站用,把网站复刻一遍)

源代码(Sources):当前的源码目录,可以打断点,用调试器调试(断点调试)

控制台(Console):写 JavaScript 代码并且输出(调试 JavaScript )

网络(Network):网络请求(抓包)

应用程序(Application):相当于 web 里面的数据库,可以存一些简单的数据保存在网页里面(查看网站的 Cookie)

3.数据类型

  • 数值、文本、图形、音频、视频……
//var:所有的变量都使用 var//number:数值( JavaScript 不区分小数和整数)
console.log(123);  //整数
console.log(123.4);  //浮点数
console.log(1.23e4);  //科学计数法,12300
console.log(-99);  //负数
console.log(NaN);  //Not a Number,不是一个数字
console.log(Infinity);  //无限大
console.log(NaN === NaN);  //NaN 与所有的数值都不相等,包括自己
console.log(isNaN(NaN));  //只能通过 isNaN() 判断是否是 NaN//浮点数问题:尽量避免使用浮点数进行运算,存在精度问题
console.log(1 / 3);  //0.3333333333333333
console.log(1 - 2 / 3);  //0.33333333333333337
//解决: Java 中有 BigDecimal ,JavaScript 可以使用绝对值
console.log(Math.abs((1 / 3) - (1 - 2 / 3)) < 0.00000001);  //true//字符串
console.log('abc');
console.log("abc");//布尔值
console.log(2 > 1);  //true
console.log(2 < 1);  //false//逻辑运算
console.log(2 > 1 && 1 < 2);  //&&:与,两个都为真,结果为真,true
console.log(2 > 1 || 1 > 2);  //||:或,一个为真,结果为真,true
console.log(!(2 > 1));  //!:非,取反,false//比较运算符
console.log();  //=:赋值
console.log(1 == "1");  //==:等于,类型不一样,值一样,也会判断为 true,true
console.log(1 === "1");  //===:绝对等于,类型一样,值一样,结果为 true,false//数组:Java 的数组必须是一系列相同类型的对象,JavaScript 中不需要这样
var arr = [1, '方括号书写', null, true];  //保证代码的可读性,建议使用
console.log(arr);  //[1, '方括号书写', null, true]
console.log(arr[4]);  //如果数组下标越界,就会 undefined
console.log(new Array(1, '对象定义', null, true));  //[1, '对象定义', null, true]//对象:对象是 {} ,每个属性之间使用 , 隔javas开,最后一个不需要添加
//Person person = new Person();
var person = {name: "zhangsan",age: 3,hobby: ['game', 'shopping', 'study']
};
console.log(person);  //{name: 'zhangsan', age: 3, hobby: Array(3)}
console.log(person.name);  //对象取值//null(空) 和 undefined(未定义)
console.log(a);  //a is not defined

4.严格检查模式 strict

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>严格检查模式strict</title><script>//如果发现 'use strict'; 报错,IDEA需要设置支持 ES 6 语法'use strict';  //严格检查模式,预防 JavaScript 的随意性导致产生的一些问题,必须写在 JavaScript 的第一行//默认全局变量,局部变量建议使用 let 定义var i = 1;  //'var' used instead of 'let' or 'const'console.log(i);//在 ES 6 中,局部变量使用 let</script>
</head>
<body></body>
</html>

三、数据类型

1.字符串

//1.正常字符串使用 '' 或 "" 包裹
console.log('a');  //a
console.log("a");  //a//2.转义字符需要 \ 转义
console.log('a\'');  //a',转义'
console.log('\u4e2d');  //中,转义 unicode 字符,\u####
console.log('\x41');  //A,转义 Ascll 编码//重要!!!
//3. ES 6 规范可以实现多行字符串编写,使用 esc 下面的 ``
console.log(`多行字符串`);//4.模板字符串
let name = "ZhangSan";
console.log("name:" + name);  //name:ZhangSan
console.log(`name:${name}`);  //name:ZhangSan,跟 EL 表达式一样//5.字符串长度
console.log(name.length);  //8,字符串长度//重要!!!
//6.字符串的可变性:不可变
console.log(name[0]);  //Z,可以通过下标取出字符串中的每一个元素
name[0] = s;
console.log(name[0]);  //赋值失败,说明字符串是不可变的//7.大小写转换
console.log(name.toUpperCase());  //ZHANGSAN,小写转大写
console.log(name.toLowerCase());  //zhangsan,大写转小写//8. indexOf() ,某个值首次出现的位置
console.log(name.indexOf('n'));  //3//重要!!!
//9. substring() ,截取字符串
console.log(name.substring(2));  //angSan,[2, ∞),从当前字符串截取到最后一个字符串
console.log(name.substring(3, 5));  //ng,[3, 5)

2.数组

  • Array 可以包含任意的数据类型
  • 数组:存取数据(如何存?如何取?方法都可以自定义实现)
//定义数组
let arr = [1, 2, 3, 4, 5, 6];  //重要!!!
console.log(arr);  //(6) [1, 2, 3, 4, 5, 6]//1.数组长度
console.log(arr.length);  //6//2.数组的可变性:可变
console.log(arr[0]);  //1,通过下标取值
arr[0] = 0;  //通过下标赋值
console.log(arr);  //(6) [0, 2, 3, 4, 5, 6]
arr.length = 10;  //假如给 arr.length 赋值,数组大小就会发生变化,如果赋值过小,元素就会丢失
console.log(arr);  //(10) [0, 2, 3, 4, 5, 6, 空 ×4]//3. indexOf() ,某个值首次出现的位置
console.log(arr.indexOf(2));  //1//字符串的 "2" 和 数值 2 是不同的
arr = [1, 2, 3, 4, 5, 6, '1', '2'];
console.log(arr.indexOf(2));  //1
console.log(arr.indexOf("2"));  //7//4. slice() ,截取数组,类似 String 中的 substring()
console.log(arr.slice(2));  //(6) [3, 4, 5, 6, '1', '2']
console.log(arr.slice(3, 5));  //(2) [4, 5]//重要!!!
//5. push() ,向数组末尾中添加值
arr.push('a', 'b');
console.log(arr);  //(10) [1, 2, 3, 4, 5, 6, '1', '2', 'a', 'b']
//6. pop() ,删除数组末尾的值
arr.pop();
console.log(arr);  //(9) [1, 2, 3, 4, 5, 6, '1', '2', 'a']//重要!!!
//7. unshift() ,向数组开头中添加值
arr.unshift('a');
console.log(arr);  //(10) ['a', 1, 2, 3, 4, 5, 6, '1', '2', 'a']
//8. shift() ,删除数组开头的值
arr.shift();
console.log(arr);  //(9) [1, 2, 3, 4, 5, 6, '1', '2', 'a']//9. sort(),排序
arr = ['B', 'C', 'A'];
console.log(arr.sort());  //(3) ['A', 'B', 'C']//10. reverse() ,元素反转
console.log(arr.reverse());  //(3) ['C', 'B', 'A']//重要!!!
//11. concat() ,拼接,并没有修改数组,只是会返回一个新的数组
console.log(arr.concat([1, 2, 3]));  //(6) ['C', 'B', 'A', 1, 2, 3]//12. join() ,替换
console.log(arr.join('-'));  //C-B-A,打印拼接数组,使用特定的字符串连接//13.多维数组
arr = [[1], ['2', '3'], ["4", "5", "6"]];
console.log(arr);  //(3) [Array(1), Array(2), Array(3)]
console.log(arr[2][1]);  //5

3.对象

  • 若干个键值对
  • JavaScript 中,{……}表示一个对象,键值对xxx: xxxx描述属性,多个属性之间使用,隔开,最后一个属性不加,
  • JavaScript 中的所有的键都是字符串,值是任意对象
var 对象名 = {属性名: 属性值,……属性名: 属性值
};
//定义对象
var person = {name: "zhangsan",age: 23,sex: '男'
};console.log(person);  //{name: 'zhangsan', age: 23, sex: '男'}
console.log(person.name);  //zhangsan//1.对象赋值 和 取值
person.name = "lisi";
console.log(person.name);  //lisi
console.log(person["age"]);  //23//2.使用一个不存在的对象属性,不会报错,undefined
console.log(person.email);  //undefined//3.动态的删减属性,通过 delete 删除对象的属性
delete person.sex;
console.log(person);  //{name: 'lisi', age: 23}//4.动态的添加属性,直接给新的属性添加值
person.sex = "女";
console.log(person);  //{name: 'lisi', age: 23, sex: '女'}//5.判断属性值是否在这个对象中
console.log("age" in person);  //true
console.log("email" in person);  //false
//继承, in 可以找到父类中的方法
console.log("toString" in person);  //true//6.判断一个属性是否是这个对象自身拥有的
console.log(person.hasOwnProperty("age"));  //true
console.log(person.hasOwnProperty("toString"));  //false

4.流程控制

  • 使用 for-in 可以遍历数组,但是会存在以下问题:( for-in 更适合遍历对象,通常是建议不要使用 for-in 遍历数组)( for-in 总是得到对象的key或数组、字符串的下标)

    1. index 索引为字符串型数字(注意,非数字),不能直接进行几何运算。
    2. 遍历顺序有可能不是按照实际数组的内部顺序(可能按照随机顺序)。
    3. 使用 for-in 会遍历数组所有的可枚举属性,包括原型。通常需要配合hasOwnProperty()方法判断某个属性是否是该对象的实例属性,来将原型对象从循环中剔除。
  • for-of 可以简单、正确地遍历数组(不遍历原型method和name)(建议是使用 for-of 遍历数组,因为for-of遍历的只是数组内的元素,而不包括数组的原型属性 method 和索引 name )( for-of 总是得到对象的value或数组、字符串的值,另外还可以用于遍历 Map 和 Set )
    1. 最简洁、最直接的遍历数组元素的语法。
    2. 这个方法避开了 for-in 循环的所有缺陷。
    3. 与 forEach() 不同的是,它可以正确响应 break 、 continue 和 return 语句。
//1. if 判断
let score = 88;
if (score > 80) {console.log("优秀");
} else if (score > 60 && score <80) {console.log("及格");
} else {console.log("不及格");
}//2. while 循环,避免程序死循环
while (score < 100) {console.log("while:" + score);score++;
}//do-while 循环
do {console.log("do-while:" + score);score++;
} while (score < 110);//3. for 循环
for (let i = 0; i < 5; i++) {console.log(i);
}//4.数组循环
let arr = [1, 2, 3, 4, 5, 6];//遍历 value ,正常遍历数组,for (let 元素值 in 对象) {}
for (let a of arr) {console.log("for...of:" + a);
}//遍历 key ,for (let 索引 in 对象) {}
for (let a in arr) {console.log("for...in:" + arr[a]);
}//通过 forEach() 函数遍历
arr.forEach(function (value) {console.log("forEach:" + value);
})

5. Map 和 Set

// ES 6 新特性
//统计:学生的成绩,学生的名字
let names = ["zhangsan", "lisi", "wangwu"];
let scores = [100, 90, 80];// Map
let map = new Map([["zhangsan", 100], ["lisi", 90], ["wangwu", 80]]);//取值
console.log(map.get("zhangsan"));  //100,通过 key 获得 value//设置值
map.set("zhaoliu", 70);
console.log(map);  //Map(4) {'zhangsan' => 100, 'lisi' => 90, 'wangwu' => 80, 'zhaoliu' => 70}//删除值
map.delete("zhaoliu");
console.log(map);  //Map(3) {'zhangsan' => 100, 'lisi' => 90, 'wangwu' => 80}// Set :无序的不重复的集合, Set 可以去重
let set = new Set([1, 1, 1, 1]);
console.log(set);  //Set(1) {1}//添加值
set.add(2);
console.log(set);  //Set(2) {1, 2}//删除值
set.delete(2);
console.log(set);  //Set(1) {1}//是否包含值
console.log(set.has(1));  //true

6. iterator 迭代器

  • 练习:使用 iterator 遍历 Map 和 Set
// ES 6 新特性
let arr = [3, 4, 5];
//遍历数组
for (let a of arr) {console.log(a);
}let map = new Map([["zhangsan", 100], ["lisi", 90], ["wangwu", 80]]);
//遍历 Map
for (let m of map) {console.log(m);
}//遍历 Set
let set = new Set([5, 6, 7]);
for (let s of set) {console.log(s);
}

四、函数及面向对象

1.定义函数

  • Java 方法:存在于对象(属性 + 方法)

    修饰符 返回值类型 方法名(参数类型 参数名){//方法体return 返回值;
    }
    
  • 函数

    1. 定义方式一:建议使用!!!
    • 注意:JavaScript 会在每一行的后面自动追加一个;,转换成浏览器能识别的语言
    • 一旦执行到return代表函数结束,返回结果
    function abs(x) {if (x >= 0) {return x;} else {return -x;}
    }
    
    1. 定义方式二:匿名函数,但是可以把结果赋值给 abs ,通过 abs 就可以调用
    var abs = function (x) {if (x >= 0) {return x;} else {return -x;}
    };
    
    • 方式一 和 方式二 等价!
    1. 调用函数:
    console.log(abs(10));  //10
    console.log(abs(-10));  //10
    //如果没有执行 return ,函数执行完也会返回结果,结果就是 undefined
    console.log(abs());  //NaN
    
  • 参数问题: JavaScript 可以传任意个参数,也可以不传参数

    • 假设参数不存在,如何规避?自定义异常,使用 typeof 判断数据类型,通过 throw 抛出异常
    function abs(x) {//使用 typeof 判断数据类型,通过 throw 手动抛出异常if (typeof x != 'number') {throw 'Not a Number';}if (x >= 0) {return x;} else {return -x;}
    }
    
    • arguments:传递进来的所有参数,是个类似数组但不是数组的对象
    function abs(x) {console.log("x:" + x);//通过 arguments 可以遍历所有传递进来的参数for (let i = 0; i < arguments.length; i++) {console.log(arguments[i]);}if (x >= 0) {return x;} else {return -x;}
    }
    
  • 问题:arguments包含所有的参数,有时候想使用多余的参数进行附加操作,需要排除已有的参数

    • 方式一:
    function f(a, b) {console.log("a:" + a);console.log("b:" + b);if (arguments.length > 2) {for (let i = 2; i < arguments.length; i++) {//...}}
    }
    
    • rest:获取除了当前变量之后的所有的参数,ES 6 新特性
    • rest参数只能写在最后面,必须使用...标识,类似 Java 可变长参数
    function f(a, b, ...rest) {console.log("a:" + a);console.log("b:" + b);console.log(rest);
    }
    

2.变量作用域

  • 在 Java 中,变量的作用域是按照块{}定义的,

    1. 局部变量:在{}里面定义的,只能在{}里面生效,
    2. 内部变量:在{}外面定义的,在整个方法都能生效,
    3. 类变量:static变量全局生效
  • 在 JavaScript 中,var 定义变量实际是有作用域的,假设在函数体中声明,则在函数体外不可以使用(闭包可以实现)

    function f() {var x = 1;x = x + 1;
    }//在 JavaScript 中,var 定义变量实际是有作用域的,假设在函数体中声明,则在函数体外不可以使用(闭包可以实现)// x = x + 2;  //Uncaught ReferenceError: x is not defined
    
  • 如果两个函数使用了相同的变量名,只要在函数内部就不冲突

    function f() {var x = 1;x = x + 1;
    }//如果两个函数使用了相同的变量名,只要在函数内部就不冲突
    function f2() {var x = 2;x = x + 2;
    }
    
  • 内部函数可以访问外部函数的成员,反之则不行

    //内部函数可以访问外部函数的成员,反之则不行
    function f3() {var x = 3;function f4() {var y = x + 4;}var z = y + 3;  //Uncaught ReferenceError: y is not defined
    }
    
  • 内部函数变量 和 外部函数变量 重名

    //内部函数变量 和 外部函数变量 重名
    //假设在 JavaScript 中,函数查找变量从自身函数开始,由“内”向“外”查找,假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量(就近原则)
    function f5() {var x = 5;function f6() {var x = 6;  //console.log('f6:' + x);}console.log('f5:' + x);f6();
    }
    
  • 提升变量的作用域

    // f7() 和 f8() 等价
    // JavaScript 执行引擎,自动提升了 b 的声明,但是不会提升 b 的赋值
    function f7() {var a = "a" + b;console.log(a);  //aundefinedvar b = "b";
    }
    function f8() {//这个是在 JavaScript 建立之初就存在的特性//在 JavaScript 中,会把所有的变量提到最前面声明,统一定义//所有的变量定义都放在函数的头部,不要乱放,便于代码维护var b;var a = "a" + b;console.log(a);  //aundefinedb = "b";
    }
    
  • 全局变量

    //全局变量: JavaScript 实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,报错 Uncaught ReferenceError
    var c = 1;
    function f9() {console.log(c);
    }
    f9();
    console.log(c);
    //全局对象 window
    console.log(window.c);  //默认所有的全局变量,都会自动绑定在 window 对象下
    window.alert(c);  // alert() :这个函数本身也是一个 window 变量var old_alert = window.alert;window.alert = function () {};
    window.alert(123);  // alert() 失效window.alert = old_alert;
    window.alert(456);  // alert() 恢复
    
  • 规范

    • 由于所有的全局变量都会绑定到window上,如果不同的 JavaScript 文件,使用了相同的全局变量,就会产生冲突,如何能够减少冲突?
    • jQuery 就是这么做的,并用简化符号$代替
    //把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题
    //唯一全局变量
    var uniqueGlobal = {};
    //定义全局变量
    uniqueGlobal.name = 'zhangsan';
    uniqueGlobal.add = function (a, b) {return a + b;
    }
    
    • 局部作用域,建议使用 let 定义局部作用域的变量
    function f10() {for (var i = 0; i < 10; i++) {console.log("var:" + i);}console.log("var:" + i);  // i 出了作用域还能使用
    }
    function f11() {// let 关键字,解决局部作用域冲突问题, ES 6 新特性for (let i = 0; i < 10; i++) {console.log("let:" + i);}console.log("let:" + i);  //Uncaught ReferenceError: i is not defined
    }
    
    • 常量
    //在 ES 6 之前,全部用大写字母命名的变量
    var PI = 3.14;
    console.log(PI);
    PI = 6.47;  //可以改变值
    console.log(PI);
    //在 ES 6 引入常量关键字 const
    const RADIUS = 5;  //只读变量
    RADIUS = 10;  //Uncaught TypeError: Assignment to constant variable.
    

3.方法

var person = {//属性name: 'zhangsan',birth: 1995,//方法:方法就是把函数放在对象里面,对象只有两个东西:属性和方法age: function () {return new Date().getFullYear() - this.birth;}
};
//调用属性
console.log(person.name);  //zhangsan
//调用方法一定要带 ()
console.log(person.age());  //27//将上面代码拆开,this 代表当前对象
function getAge() {return new Date().getFullYear() - this.birth;
}var student = {name: 'lisi',birth: 2008,age: getAge
};
console.log(student.age());  //14
// this 指向使用它的对象,此时 window 使用, window 没有 birth 属性
console.log(getAge());  //NaN// this 是无法指向的,默认指向调用它的对象
//在 js 中可以使用 apply 控制 this 的指向
// apply(对象, 参数)
getAge.apply(student, []);  // this 指向了 student 对象,参数为空
console.log(getAge.apply(student, []));  //14

4.内部对象

//标准对象
console.log(typeof 123);  //number
console.log(typeof '123');  //string
console.log(typeof true);  //boolean
console.log(typeof NaN);  //number
console.log(typeof []);  //object
console.log(typeof {});  //object
console.log(typeof Math.abs);  //function
console.log(typeof undefined);  //undefined

1.Date

//标准对象//Date
//基本使用
let now = new Date();
console.log(now);  //Wed Jan 05 2022 19:32:54 GMT+0800 (中国标准时间)
console.log(now.getFullYear());  //年
console.log(now.getMonth());  //月 0~11
console.log(now.getDate());  //日
console.log(now.getDay());  //星期
console.log(now.getHours());  //时
console.log(now.getMinutes());  //分
console.log(now.getSeconds());  //秒
console.log(now.getTime());  //时间戳,格林威治时间 1970.1.1 0:00:00 毫秒数
//转换
console.log(new Date(1641382588634));  //时间戳 转为 时间
//注意:调用的是方法,不是属性
console.log(now.toLocaleString());  //转换为本地时间 2022/1/5 下午7:41:37

2.JSON

  • 以前,所有的数据传输习惯使用 XML 文件
  • JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。
  • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
  • BSON 也是一种数据交换格式,主要用在 MongoDB 中,名字源于 JSON ,是二进制的 JSON
  • 在 JavaScript 中,一切皆对象,任何 js 支持的类型都可以用 JSON 表示
  • 格式:
    • 对象:{}
    • 数组:[]
    • 键值对:key: value
// person 对象
let person = {name: 'zhangsan',age: 3,sex: '男'
};
console.log(person);  //{name: 'zhangsan', age: 3, sex: '男'}//对象 转化为 JSON字符串(字符串化)
let jsonPerson = JSON.stringify(person);
console.log(jsonPerson);  //{"name":"zhangsan","age":3,"sex":"男"}// JSON字符串 转化为 对象(解析),参数为 JSON 字符串
let objPerson = JSON.parse('{"name":"zhangsan","age":3,"sex":"男"}');
console.log(objPerson);  //{name: 'zhangsan', age: 3, sex: '男'}// JSON字符串 和 js对象 的区别
let obj = {name: 'zhangsan', age: 23};
let json = '{"name":"zhangsan", "age": 23}';

3.AJAX

  • 原生的 js 写法, xhr 异步请求
  • jQuery 封装好的方法$.ajax({url, data, success})
  • axios 请求,就是一个 jar 包,专门用来做请求的

5.面向对象编程

1.原型继承(难点)

  • JavaScript、Java、C#……都有一个面向对象的特性

  • 面向对象有两个重要的东西:类和对象

    • 类:模板(类是对象的抽象)

    • 对象:具体的实例(对象是类的具体表现)

  • JavaScript有一些区别

    • 原型:模板
  • 原型链

    • 在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VaniqpQT-1646469936158)(https://cdn.jsdelivr.net/gh/327506144/picx-xpoet-cn@master/20210626/原型链.webp)]

//1.原型 继承
let person = {name: 'zhangsan',age: 23,run: function () {console.log(this.name + '跑步');}
};let lisi = {name: 'lisi'
};
// lisi 的原型是 person
lisi.__proto__ = person;
lisi.run();  //lisi跑步let bird = {fly: function () {console.log(this.name + '飞行');}
};
// lisi 的原型是 person
lisi.__proto__ = bird;
lisi.fly();  //lisi飞行

2.class 继承( ES 6 新特性)

//2. class 继承
function User(name) {this.name = name;
}//给 User 新增一个方法
User.prototype.hello = function () {console.log('hello');
};// class 关键字,是在 ES 6 引入的
//定义一个老师类,属性、方法
class Teacher {//构造器constructor(name) {this.name = name;}//方法hello() {console.log('es6...class...hello');}
}let wangwu = new Teacher('wangwu');
console.log(wangwu.hello());
let zhaoliu = new Teacher('zhaoliu');
console.log(zhaoliu.hello());//继承:本质还是查看对象原型
class Student extends Teacher {constructor(name, grade) {super(name);this.grade = grade;}score() {console.log('学生分数');}
}let sunqi = new Student('sunqi', 60);
console.log(sunqi.score());  //学生分数

五、操作 BOM 元素(重点)

  • BOM :浏览器对象模型

  • 浏览器介绍

    • JavaScript 和 浏览器的关系?

      • JavaScript 诞生就是为了能够在浏览器中运行
    • IE 6~11:8 之前的版本很老,里面很多功能不支持

    • 内核:

      • Chrome:谷歌浏览器

      • Safari:苹果浏览器

      • FireFox:火狐浏览器,Linux 系统默认浏览器

      • Opera:欧朋浏览器

    • 第三方浏览器

      • QQ 浏览器:
      • 360 浏览器:

1. window(浏览器窗口)(重要)

  • window:代表浏览器窗口

  • window对象默认可以不写

//弹窗
window.alert('alert弹窗');
//视窗宽高
console.log(window.innerHeight);  //内部高度
console.log(window.innerWidth);  //内部宽度
//浏览器宽高
console.log(window.outerHeight);  //外部高度
console.log(window.outerWidth);  //外部宽度
//可以调整浏览器窗口试试

2. navigator(浏览器)(不建议使用)

  • navigator:封装了浏览器的信息
  • 可以检测当前浏览器是否合适玩某个网页游戏,可以检测电脑浏览器还是手机浏览器
  • 通常不会使用navigator对象,因为会被人为修改,不建议使用这些属性判断和编写代码
//浏览器名称
console.log(navigator.appName);  //Netscape,网景
//浏览器版本
console.log(navigator.appVersion);  //5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62
//浏览器设置的语言
console.log(navigator.language);  //zh-CN
//操作系统类型
console.log(navigator.platform);  //Win32
//浏览器设定的 User-Agent 字符串
console.log(navigator.userAgent);  //Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62

3. screen(屏幕)

  • screen:代表全屏幕属性
//计算机屏幕宽度
console.log(screen.width);  //1920 px
//计算机屏幕高度
console.log(screen.height);  //1080 px

4. location(URL信息)(重要)

  • location:代表当前页面的URL信息
//主机
console.log(location.host);
//当前页面的 URL
console.log(location.href);
// web 协议(http: 或 https:)
console.log(location.protocol);
//重新加载当前页面,刷新网页
location.reload();
//加载一个新页面,设置一个新的URL地址
location.assign('https://www.baidu.com/');

5. document(文档)(重要)

  • document:代表当前页面
  • HTML 有一个 DOM 文档树,document对象就是整个DOM树的根节点。
  • 可以直接拿到网页的 cookie , cookie 是会被劫持的,恶意人员会获取你的 cookie 上传到他的服务器,甚至可以伪造 cookie ,可以实现不需要用户名和密码就可以登陆,服务器端可以设置 cookie 为httpOnly,确保安全性
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>document</title><script>'use strict';//获取网页标题console.log(document.title);  //document//改变网页标题document.title = '改变网页标题';//获取当前网页的 cookieconsole.log(document.cookie);</script>
</head>
<body><dl id="app"><dt>Java</dt><dd>JavaSE</dd><dd>JavaEE</dd><dd>JavaME</dd></dl><script>//获取具体的文档树节点let dl = document.getElementById('app');console.log(dl);</script>
</body>
</html>

6. history(历史)(不建议使用)

  • history:代表浏览器的历史记录
//返回
history.back();
//前进
history.forward();

六、操作 DOM 元素(重点)

  • DOM:文档对象模型

  • 核心:整个浏览器网页就是 DOM 树形结构

    • 更新 DOM 节点:更新节点内容

    • 遍历 DOM 节点:得到 DOM 节点

    • 删除 DOM 节点:删除该节点及它的所有子节点

    • 添加 DOM 节点:新增一个子节点

  • 要操作一个 DOM 节点,就必须要先获得这个 DOM 节点

1.获得 DOM 节点

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>获得DOM节点</title>
</head>
<body><div id="father"><h1>标题1</h1><p id="p1">p1</p><p class="p2">p2</p>
</div><script>'use strict';//通过 标签名 查找 HTML 元素,h1 标签let h1 = document.getElementsByTagName('h1');console.log(h1);//通过 id 查找 HTML 元素,id="p1"let p1 = document.getElementById('p1');console.log(p1);//通过 类名 查找 HTML 元素,对应 css 选择器,class="p2"let p2 = document.getElementsByClassName('p2');console.log(p2);let father = document.getElementById('father');//获取父节点下的所有子节点let children = father.children;//获取父节点下的第一个子节点let first = father.firstElementChild;//获取父节点下的最后一个子节点let last = father.lastElementChild;
</script>
</body>
</html>
  • 这是原生代码,之后尽量使用 jQuery();

2.更新 DOM 节点

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>更新DOM节点</title>
</head>
<body><div id="father"></div><script>'use strict';let father = document.getElementById('father');//操作文本//修改文本的值father.innerText = '123';//可以解析 HTML 文本标签father.innerHTML = '<strong>123</strong>'//操作 cssfather.style.color = 'red';father.style.fontSize = '30px';  //- 转 驼峰命名,css 中的 font-size
</script>
</body>
</html>

3.删除 DOM 节点

  • 删除节点的步骤:先获取父节点,再通过父节点删除自己
  • 删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>删除DOM节点</title>
</head>
<body><div id="father"><h1>标题1</h1><p id="p1">p1</p><p class="p2">p2</p>
</div><script>'use strict';//1.获取待删除节点let self = document.getElementById('p1');//2.获取父节点let father = self.parentElement;//3.通过父节点删除字节点father.removeChild(p1);//通过指定的下标删除,删除是一个动态的过程,不建议这样使用//注意:删除多个节点的时候, children 是在时刻变化的father.removeChild(father.children[0]);
</script>
</body>
</html>

4.插入 DOM 节点

  • 我们获得了某个 DOM 节点,假设这个 DOM 节点是空的,可以通过innerTextinnerHTML增加一个元素,但是当这个 DOM 节点已经存在元素,就不能这么做!因为会产生覆盖
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>插入DOM节点</title><link rel="stylesheet" href="" type="text/css"><script type="text/javascript" src=""></script>
</head>
<body><p id="java">Java</p>
<div id="father"><p id="se">JavaSE</p><p id="ee">JavaEE</p><p id="me">JavaME</p>
</div><script>//把已存在的节点追加到父节点最后let java = document.getElementById('java'),father = document.getElementById('father');//插入的节点已存在于当前文档树,这个节点会先从原来的位置删除,再插入到新的位置father.appendChild(java);//通过 js 创建一个新的节点//1.创建一个 p标签let p = document.createElement('p');//2.设置 idp.id = 'js';//3.为 p标签 增加内容p.innerText = 'JavaScript';//4.将 p标签 追加到父节点最后father.appendChild(p);//1.创建标签节点let script = document.createElement('script');//2.设置节点属性 type="text/javascript"script.setAttribute('type', 'text/javascript');father.appendChild(script);// getElementsByTagName 返回的是集合let body = document.getElementsByTagName('body');body[0].style.background = 'gray';//把一个节点插入到指定节点前面let ee = document.getElementById('ee');//父节点.insertBefore(新节点, 参考子节点);father.insertBefore(js, ee);
</script>
</body>
</html>

七、操作表单(验证)

1.表单是什么?

  • 表单本身也是 DOM 树

  • 文本框:<input type="text">

  • 密码框:<input type="password">

  • 下拉框:<select>

  • 单选框:<input type="radio">

  • 复选框:<input type="checkbox">

  • 隐藏域:<input type="hidden">

  • 表单的目的:提交信息

2.获得要提交的信息

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>获得要提交的信息</title>
</head>
<body><form action="" method="post"><p><label for="username">姓名:</label><input type="text" name="username" id="username"></p><!--单选框和多选框的值,就是定义好的 value--><p><span>性别:</span><input type="radio" name="gender" id="man" value="man">男<input type="radio" name="gender" id="woman" value="woman">女</p>
</form><script>'use strict';let username = document.getElementById('username');//得到输入框的值console.log(username.value);//修改输入框的值username.value = 'zhangsan';//对于单选框、复选框等,.value 只能取到预设的值let man = document.getElementById('man');let woman = document.getElementById('woman');console.log(man.value);console.log(woman.value);//查看返回的结果是否为 true ,如果为 true 则被选中console.log(woman.checked);//赋值woman.checked = true;
</script></body>
</html>

3.提交表单

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>提交表单</title><!--MD5 工具类--><script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
</head>
<body><!--提交表单方式二:-->
<!--表单绑定提交事件,需要使用 onsubmit 绑定一个提交检测的函数,获取函数返回的 true / false 结果给表单,使用 onsubmit 接收-->
<form action="" method="post" id="test-form" onsubmit="return check()"><p><span>姓名:</span><input type="text" name="username" id="username"></p><p><span>密码:</span><input type="password" name="password" id="password"></p><!--表单优化--><p><span>密码:</span><input type="password" id="input-password"></p><!--利用隐藏域传递数据--><input type="hidden" name="password" id="md5-password"><!--提交表单方式一:为 button 绑定事件,通过 form.submit() 提交表单,扰乱了浏览器对form的正常提交-->
<!--    <button οnclick="doSubmitForm()">提交</button>--><input type="submit">
</form><script>'use strict';function check() {let username = document.getElementById('username'),password = document.getElementById('password'),//明文密码inputPassword = document.getElementById('input-password'),// MD5 加密密码md5Password = document.getElementById('md5-password');console.log('加密前' + password.value);//MD5 算法加密password.value = md5(password.value);console.log('加密后' + password.value);//把密码框的明文密码用 MD5 加密,通过隐藏域把加密密码发送后台md5Password.value = md5(inputPassword.value);//可以校验判断表单内容, true 通过提交, false 阻止提交return true;}// 提交表单方式一:// function doSubmitForm() {//     var form = document.getElementById('test-form');//     // 可以在此修改form的input...//     // 提交form://     form.submit();// }
</script></body>
</html>

八、jQuery库

  • JavaScript 和 jQuery 的关系:

    • jQuery 就是封装了大量 JavaScript 方法的库

1.获取 jQuery

  1. 官网下载获取,有 compressed(已压缩,生产)和 uncompressed(未压缩,开发)两种版本,直接引入到项目

    • 官网:jQuery

    • 文档:jQuery API 中文文档

  2. 百度搜索”CDN jQuery“
    • CDN jQuery:jQuery cdn加速 (jq22.com)
  • 公式:$(选择器).事件(事件函数);
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>获取jQuery</title><!--1.引入 JavaScript 在线 CDN --><!--    <script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>--><!--2.引入 jQuery 文件--><script src="lib/jquery-3.6.0.js"></script>
</head>
<body><!--公式:$(selector).action();-->
<!-- selector 就是 CSS 选择器-->
<a href="" id="test-jquery">点击</a><script>'use strict';//原生的document.getElementById('test-jquery');//jQuery$('#test-jquery').click(function () {alert('jQuery');})
</script>
</body>
</html>

2.选择器

// JavaScript 原生选择器,少
//标签选择器
document.getElementsByTagName('p');
//id 选择器
document.getElementById('id');
//类选择器
document.getElementsByClassName('class');// jQuery 选择器, CSS 的选择器都能用
//标签选择器
$('p');
//id 选择器
$('#id');
//类选择器
$('.class');

3.事件

  • 鼠标事件

    • click: 鼠标单击时触发;

    • dblclick:鼠标双击时触发;

    • mouseenter:鼠标进入时触发;

    • mouseleave:鼠标移出时触发;

    • mousemove:鼠标在DOM内部移动时触发;

    • hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave。

  • 键盘事件

    • keydown:键盘按下时触发;
    • keyup:键盘松开时触发;
    • keypress:按一次键后触发
  • 其它事件

    • focus:当DOM获得焦点时触发;
    • blur:当DOM失去焦点时触发;
    • change:当<input><select><textarea>的内容改变时触发;
    • submit:当<form>提交时触发;
    • ready:当页面被载入并且DOM树完成初始化后触发。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>事件</title><script src="lib/jquery-3.6.0.js"></script><style>#divMove{width: 600px;height: 500px;border: 1px solid black;}</style>
</head>
<body>mouse:<span id="mouseMove"></span>
<div id="divMove">在这里移动鼠标试试</div><script>'use strict';//当网页元素加载完毕之后,响应事件// $(document).ready(function () {//// })// document 默认就是文档, ready() 默认就是加载完,由于ready事件使用非常普遍,所以可以这样简化:$(function () {$('#divMove').mousemove(function (e) {//获取鼠标当前坐标$('#mouseMove').text('x:' + e.pageX + ',y:' + e.pageY);})})
</script></body>
</html>

4.操作 DOM 元素

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>操作DOM元素</title><script src="lib/jquery-3.6.0.js"></script>
</head>
<body><ul id="test-ul"><li class="se">JavaSE</li><li name="ee">JavaEE</li>
</ul>
<button οnclick="toggle_ul()">切换隐藏/显示</button>
<script>'use strict';//属性选择器let ee = $('#test-ul li[name=ee]');//获取值//操作文本console.log(ee.text());//可以解析 HTML 文本标签console.log(ee.html());//设置值ee.text('123');ee.html('<strong>123</strong>');//操作 cssee.css('color', 'red');//隐藏和显示 DOM :本质,display: noneee.hide();ee.show();// window 宽高:浏览器可视窗口大小console.log($(window).width());console.log($(window).height());// document 宽高:HTML文档大小console.log($(document).width());console.log($(document).height());function toggle_ul() {//如果元素是可见的,切换为隐藏的;如果元素是隐藏的,切换为可见的。$('#test-ul').toggle();}
</script>
</body>
</html>

5.Ajax

$('#from').ajax();$.ajax({ url: "test.html", context: document.body, success: function(){$(this).addClass("done");
}});

九、开发技巧

  1. 如何巩固 js ?

    1. 看 jQuery 源码

    2. 看游戏源码

  2. 如何巩固 HTML 和 CSS ?

    1. 扒网站,全部 down 下来,然后对应修改看效果

20.JavaScript6相关推荐

  1. 利用php屏蔽海外ip访问,高效实现

    <?php/*** 屏蔽海外ip访问* 使用ip2long函数得到ip转为整数的值,判断值是否在任一一个区间中* 以下是所有国内ip段* 调用方法:IschinaIp($ALLIPS)* 返回值 ...

  2. python减小内存占用_如何将Python内存占用缩小20倍?

    当程序执行过程中RAM中有大量对象处于活动状态时,可能会出现内存问题,特别是在对可用内存总量有限制的情况下. 下面概述了一些减小对象大小的方法,这些方法可以显著减少纯Python程序所需的RAM数量. ...

  3. ADAS摄像头20个技术挑战

    ADAS摄像头20个技术挑战 车载相机已经成为现代汽车中不可或缺的一部分,不论在辅助驾驶还是在自动驾驶应用领域,越来越多的相机装备在机车上. 根据Tesla现在的配置,全车有9个Camera. 根据W ...

  4. 嵌入式开发在过去20年中是如何演变的

    嵌入式开发在过去20年中是如何演变的 How embedded development has evolved over the past two decades 与任何开发领域一样,嵌入式系统开发就 ...

  5. uwsgi 安装报错 plugins/python/uwsgi_python.h:2:20: fatal error: Python.h: No such file or directory

    1. Python3 安装 uwsgi 报错 直接使用命令 sudo pip3 install uwsgi 安装如下错误: ubuntu@ubuntu:~/Downloads$ sudo pip3 i ...

  6. 20. Valid Parentheses

    判断括号是否匹配 知道要用栈来做,但是过程还是想了一会儿,哎 1 bool isValid(char* s) { 2 int len = 0; 3 while(s[len++] != '\0'); 4 ...

  7. 第20章 使用LNMP架构部署动态网站环境

    章节概述: 本章节将从Linux系统的软件安装方式讲起,带领读者分辨RPM软件包与源码安装的区别.并能够理解它们的优缺点. Nginx是一款相当优秀的用于部署动态网站的服务程序,Nginx具有不错的稳 ...

  8. 如何释放电脑被限制的20%网速?

    很多朋友不管是看电影还是玩游戏,总觉得自己的网速慢,这跟自己所办网络的带宽有一定关系,但我们也要知道,我们的电脑在买来时,默认是限制了20%网速的,如何释放这20%的网速,提高用户体验呢!" ...

  9. Android OpenGL ES(十一)绘制一个20面体 .

    前面介绍了OpenGL ES所有能够绘制的基本图形,点,线段和三角形.其它所有复杂的2D或3D图形都是由这些基本图形构成. 本例介绍如何使用三角形构造一个正20面体.一个正20面体,有12个顶点,20 ...

最新文章

  1. OpenDataSource,sql开放式数据源
  2. Web服务器安全设置
  3. python桌面快捷图标_python 创建桌面快捷方式 | 学步园
  4. 1593: 01串(找规律)
  5. android操作系统 真的吗_旋挖机培训学校真的能学会吗,旋挖钻机到底有哪些操作系统...
  6. python Json的一点收获,自定义序列化方法
  7. 前端学习(1044):本地存储实现数据录入
  8. 链地址处理哈希冲突方法
  9. mac安装cmake
  10. Linked List Sorting (链表)
  11. Net::OpenSSH 模块使用实例
  12. linux审计日志清除,Linux登录安全及用户操作审计 ,linux下清理日志脚本
  13. ajax如何用编号查询姓名,Ajax js 使用Ajax检测用户名是否存在
  14. 商业智能BI有哪些数据价值
  15. C3模块-空洞可分离卷积存在的问题及轻量化语义分割模型架构技巧
  16. Fortran95学习笔记
  17. 嵌入式系统之CMSIS学习笔记
  18. OPNET网络仿真实验
  19. iPhone IPv6上网
  20. 你应该了解的GPS经纬度

热门文章

  1. 小米手机开发版、稳定版刷机和root等操作
  2. 蚂蚁金服大规模分布式事务实践和开源详解
  3. 判断两个字符串是不是互为anagrams
  4. 同一台 win10 服务器跑多个 wiki(包括 DokuWiki、django-wiki)
  5. 【leetcode】青蛙跳楼梯问题
  6. Two Sequences (二分+二进制) (好题)
  7. Java银行卡校验API
  8. NextCloud安装配置小白教程~
  9. idmp用户唯一标识图计算模拟演示
  10. python微服务架构设计模式_微服务架构设计模式 PDF 电子书 百度云 网盘下载