20.JavaScript6

news/2024/10/31 13:24:56/

一、什么是 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,这样的话语法更严谨

修改JavaScript语法版本

基本语法入门

  • 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 下来,然后对应修改看效果

http://www.ppmy.cn/news/170719.html

相关文章

JavaScriptES6

ES5高级ES6广域学习 学习笔记 面向对象的编程语言&#xff08;OOP&#xff09; 什么是面向对象的编程语言&#xff1f; • 一切皆对象&#xff0c;对象的模板是类&#xff0c;类的实例是对象(当然js中没有类的概念,class只是语法糖) • 对象中有属性、方法&#xff0c;属性的…

JavaScript(ES5)

JavaScript&#xff08;ES5&#xff09; 基础数据类型 Number、String、Boolean、undefined、object、Null Number JavaScript 只有一种数字类型。数字可以带小数点&#xff0c;也可以不带&#xff1a; let x134.00; //使用小数点来写 let x234; //不使用小数…

JavaScript 62 JavaScript 版本 62.6 ECMAScript 2018

JavaScript 文章目录 JavaScript62 JavaScript 版本62.6 ECMAScript 201862.6.1 ECMAScript 2018 中的新特性62.6.2 JavaScript 异步迭代62.6.3 JavaScript Promise.finally62.6.4 JavaScript 对象 Rest 属性62.6.5 新的 JavaScript RegExp 特性 62 JavaScript 版本 62.6 ECMA…

JavaScriptES6(三)

一、函数 1、函数形参的默认值&#xff1a;在很多情况下,需要在使用函数的时候给定默认参数,在ES5标准中一般会这样写&#xff1a; function fun(name,age,cb){name typeof(name ! undefined)?name: 张三age typeof(age ! undefined)?age: 20cb typeof(cb ! undefined)?…

ECMAScript 6 (13) async 函数

ES2017 标准引入了 async 函数&#xff0c;使得异步操作变得更加方便。 async 函数是什么&#xff1f;一句话&#xff0c;它就是 Generator 函数的语法糖。 前文有一个 Generator 函数&#xff0c;依次读取两个文件。 const fs require(fs);const readFile function (file…

JavaScript 5

一、for循环 1、for循环的语法和执行顺序 for(参数初始化 ; 条件判断; 更新循环变量){ 循环体被执行; } 参数&#xff1a;可以声明多个同一 类型的值并赋值&#xff0c;用“&#xff0c;”隔开 循环变量&#xff1a;可以是用“&#xff0c;”隔开的多 个表达式&#xff0c;运…

JavaScript 66 JavaScript Async 66.4 JavaScript Async

JavaScript 文章目录 JavaScript66 JavaScript Async66.4 JavaScript Async66.4.1 Async 语法66.4.2 Await 语法66.4.3 浏览器支持 66 JavaScript Async 66.4 JavaScript Async “async and await make promises easier to write” async 使函数返回 Promise await 使函数等…

JavaScriptES6(一)

一、let及const 1、是ES6新增的两种新的声明格式&#xff0c;用于补全ES5标准中var声明变量的不足&#xff1a;在JavaScript中用var来声明变量会出现变量提升的情况&#xff0c;即通过"var"声明的变量&#xff0c;系统都会把声明隐式的升至顶部&#xff0c;这样的特…