JavaScript 笔记
Yuxuan Wu Lv13

什么是JavaScript

概述

JavaScript 是一门世界上最流行的脚本语言

Java、JavaScript

==一个合格的后端人员,必须精通javascript==

快速入门

引入JavaScript

  1. 内部标签
1
2
3
<script>
//...
</script>
  1. 外部引入

abs.js

1
//...

test.html

1
<script src="abs.js"></script>
  1. 测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>

<!-- script 标签内,写javascript代码-->
<!-- <script>-->
<!-- alert('hello world');-->
<!-- </script>-->

<!-- 外部引入-->
<!-- 注意:script必须成对出现-->
<script src="js/first_js.js"></script>


</head>
<body>
<!--这里也可以存放-->

</body>
</html>

基本语法入门

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
// 1. 定义变量 变量类型 变量名 = 变量值
var score =71;
var name = "yuxuan";

// 2. 条件控制
if(score>60&&score<70){
alert("60-70")
}else if(score>70&&score<80){
alert("70-80")
}else {
alert("other")
}

// console.log 打印变量,相当于在浏览器打印变量 == 类似sout

/*
asdasd
*/

</script>
</head>
<body>

</body>
</html>

浏览器必备调整须知

image-20210408130340788

数据类型

数值,文本,图形,音频,视频…

==变量==

1
var a 

==number==

js不区分小数和整数

1
2
3
4
5
6
123 //	整数123
123.1 // 浮点数123.1
1.123e3 // 科学计数法
-99 //负数
NaN // not a number
Infinity // 表示无限大

==字符串==

‘abc’ “abc “

==布尔值==

true,false

==逻辑运算==

1
2
3
4
5
&& 

||

!

==比较运算符==

1
2
3
=
== 等于(类型不一样,值一样,也会判断为true, e.g. “1”=1true
=== 绝对等于 (类型一样,值一样,结果为true

这是一个JS的缺陷,简直不要使用==的比较

须知:

  • NaN==NaN, 这个与所有的数值都不相等,包括自己
  • 只能通过isNaN(NaN)来判断这个数是不是NaN

==浮点数问题==

1
console.log((1/3)===(1-2/3)) // 计算机不支持无限大的数,会有精度的损失

尽量避免使用浮点数进行运算,因为存在精度问题

1
console.log(Math.abs(1 / 3 - (1 - 2 / 3)) < 0.00000001) // 计算机不支持无限大的数,会有精度的损失

==null和undefined==

  • Null 空
  • Undefined 未定义

==数组==

Java的数值必须是一系列相同类型的变量,JS中并不要求这样

1
2
3
4
// 保证代码的可读性,尽量使用[]
var arr=[1,2,3,4,5,'hello',null, true]

new Array(1,12,3,4,6,'hello')

取数组下标:如果越界了,就会undefined

==对象==

对象是大括号,数组是中括号

每个属性之间使用逗号隔开,最后一个不需要添加

1
2
3
4
5
6
// Person person = new Person(1,2,3,4)
var person={
name: "yuxuan",
age: 3,
tags: ['js','java','...']
}

取对象的值

1
2
3
4
person.name
>"yuxuan"
person.age
>3

严格检查格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--
前提:IDEA需要设置支持ES6的语法

必须写在JavaScript的第一行
'use strict'; 严格检查模式,防止Javascript导致产生的一些问题
局部变量建议都使用let去定义~
-->
<script>
'use strict';
// 全局变量
let i = 1;
// ES6 let
</script>
</head>
<body>

</body>
</html>

数据类型

字符串

  1. 正常的字符串我们使用’’ 和“ ”包裹
  2. 注意转义字符
1
2
3
4
5
\'
\n
\t
\u4e2d unicode字符
\x41 Ascll 字符
  1. 多行字符串编写
1
2
3
4
5
6
'use strict'
// 反引号
var msg =`
hello
world

  1. 模版字符串
1
2
3
4
var name = "yuxuan";
var age = 3;
var msg =`你好呀 ${name}`
console.log(msg)
  1. 字符串长度
1
str.length 
  1. 字符串的可变性,不可变
1
2
3
4
5
6
7
8
console.log(student[0])
> s
< undefined
student[0] = 1
> 1
console.log(student)
> student
< undefined
  1. 大小写转换
1
2
3
4
//注意,这里是方法,不是属性了

student.toUpperCase()
student.toLowerCase()
  1. 获取索引
1
student.indexOf('s')
  1. substring
1
2
3
[)
student.substring(1) // 从第一个字符串截取到最后一个字符串
student.substring(1,3) //[1,3)

数组

Array 可以包含人意的数据类型

1
2
3
var arr = [1,2,3,4,5,6]; // 通过下标取值和赋值
arr[0]
arr[0]=1
  1. 长度
1
arr.length()

注意:假如给arr.length 赋值,数据大小就会发生变化~ 如果赋值过小,元素就会丢失

  1. indexOf,通过元素获得下标索引
1
2
arr.indexOf(2)
1

注意:字符串的“1”和1是不同的

  1. slice() 截取Array的一部分,返回一个新数组, 类似于String中的substring
  1. push() , pop()
1
2
push: 压入到尾部
pop: 弹出尾部的一个元素
  1. unshift(), shift(), 头部
1
2
unshift: 压入到头部
shift: 弹出头部的一个元素
  1. 排序 sort()
1
2
3
4
arr
>(3) ["B", "C", "A"]
arr.sort()
>(3) ["A", "B", "C"]
  1. 元素反转
1
2
3
(3) ["A", "B", "C"]
arr.reverse()
(3) ["C", "B", "A"]
  1. concat()
1
2
3
4
5
(3) ["C", "B", "A"]
arr.concat(1,2,3)
(6) ["C", "B", "A", 1, 2, 3
arr
(3) ["C", "B", "A"]

注意:concat() 并没有修改数组,只是会返回一个新的数组

  1. 连接符号join

打印拼接数组,使用特定的字符串链接

1
2
3
(3) ["C", "B", "A"]
arr.join('-')
"C-B-A"
  1. 多维数组
1
2
3
arr = [[1,2],[3,4],["5","6"]]
arr[1][1]
4

数组:存储数据(如何存,如何取,方法都可以自己实现!)

对象

若干个键值对

1
2
3
4
5
6
7
8
9
10
11
12
var 对象名 = {
属性名: 属性值,
属性名: 属性值,
属性名: 属性值,
}

var person = {
name: "yuxuan",
age:3,
email: "123213@qq.com",
score:0
}

JS中的对象,{…}表示一个对象,键值对描述属性 xxxx: xxxx 多个属性之间使用逗号隔开,最后一个属性不加逗号!

JavaScript 中的所有键都是字符串,值是任意对象

  1. 对象赋值
1
2
3
4
person.name="yuxuanwu"
"yuxuanwu"
person.name
"yuxuanwu"
  1. 使用一个不存在的对象属性,不会报错! undefined
1
2
person.hah
undefined
  1. 动态的删减属性,通过delete删除对象的属性
1
2
3
delete person.name
true
person
  1. 动态的添加,直接给新的属性添加值即可
1
2
3
person.haha = "haha"
"haha"
person
  1. 判断属性值是否在这个对象中! Xxx in xxx!
1
2
3
4
5
'age' in person
true
// 继承
'toString' in person
true
  1. 判断一个属性是否是这个对象自身拥有的 hasOwnProperty
1
2
3
4
person.hasOwnProperty('age')
true
person.hasOwnProperty('toString')
false

流程控制

if 判断

1
2
3
4
5
6
7
8
9
var age = 3;
if (age>3){ // 第一个判断
alert("haha")
}else if (age<5){ //第二个判断
alert("md")
}
else { //否则。。
alert("kuwa~")
}

while 循环,避免程序死循环

1
2
3
4
5
var age = 3;
while (age<100){
age = age+1
console.log(age);
}

for循环

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

forEach 循环

1
2
3
4
5
6
var age = [12,3,324,12312,245,21,3]

// 函数
age.forEach(function (value){
console.log(value)
})

数组循环(for…in)

1
2
3
4
5
6
var age = [12,3,324,12312,245,21,3]

// 函数
for (var index in age){
console.log(age[index]);
}

数组循环(for…of)

1
2
3
4
var arr = [3, 4, 5];
for (var x of arr){
console.log(x)
}

Map 和 Set

ES6的新特性

Map:

1
2
3
4
5
6
7
8
9
// ES6 Map 和python字典类似
// 学生的成绩,学生的名字
// var names = ["tom", "haha", "jack"];
// var score = [100, 90, 80];
var map = new Map([['tom',100],['jack',90],['haha',80]]);
var name = map.get('tom') // 通过key来获得value
map.set('admin',123456) // 新增或者修改
map.delete("tom") //删除
console.log(name)

Set: 无序不重复的集合

1
2
3
set.add(2); // 添加
set.delete(1); //删除
console.log(set.has(3)); // 是否包含某个元素

Iterator

遍历数组

1
2
3
4
var arr = [3, 4, 5];
for (var x of arr){
console.log(x)
}

遍历map

1
2
3
4
var map = new Map([['tom',100],['jack',90],['haha',80]]);
for (let x of map) {
console.log(x);
}

遍历set

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

函数

方法:对象(属性,方法)

定义函数

java 里面的定义

1
2
3
public 返回值类型 方法名(){
return ...
}

定义方式一

绝对值函数

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

一旦执行return代表方法结束,返回结果!

如果没有执行return,函数执行完也会返回结果,结果就是undefined

定义方式二

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

function(x){…}这是一个匿名函数,但是可以吧结果给abs,通过abs可以调用函数

方式一和方式二等价

调用函数

1
2
abs(10) //10 
abs(-10) //10

参数问题:javascript 可以传递任意参数,也可以不传递参数

参数进来是否存在的问题?

假设不存在参数,如何规避?

1
2
3
4
5
6
7
8
9
10
11
function abs(x){
// 手动跑出异常
if (typeof x!=='number'){
throw 'Not a number'
}
if(x>=0){
return x;
}else{
return -x;
}
}

arguments

arguments是一个免费赠送的关键字

代表,传递进来的所有参数,是一个数组

1
2
3
4
5
6
7
8
9
10
11
12
13
function abs(x){

console.log("x>" + x);
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}

if(x>=0){
return x;
}else{
return -x;
}
}

问题:arguments包含所有的参数,我们有时候想使用多余的参数来进行操作。需要排除已有的参数

rest

以前:

1
2
3
4
5
if (arguments.length > 2) {
for (let i = 2; i < arguments.length; i++) {
//...
}
}

ES6 引入的新特性,获取除了已经定义的参数之外的所有参数~ …

1
2
3
4
5
function aaa(a, b, ...rest) {
console.log("a=>" + a);
console.log("b=>" + b);
console.log(rest)
}

变量的作用域

在JavaScript中,var的定义变量实际是有作用域的

假设在函数体中声明,则在函数体外不可以使用~(闭包可以实现,但是难)

1
2
3
4
5
6
function qj(){
var x = 1;
x = x + 1;
}

x = x + 2 //Uncaught ReferenceError: x is not defined

如果两个函数使用了相同的变量名,只要在函数内部,就不冲突

1
2
3
4
5
6
7
8
9
function qj(){
var x = 1;
x = x + 1;
}

function qj2(){
var x = 'A';
x = x + 1;
}

内部函数可以访问外部函数的成员,反之则不行

1
2
3
4
5
6
7
8
9
10
11
12
function qj() {
var x = 1;


// 内部函数可以访问外部成员函数,反之则不行
function qj2() {
var y = x + 1;

}

var z = y + 1;
}

假设,内部函数变量和外部函数的变量,重名!

1
2
3
4
5
6
7
8
9
10
11
12
function qj() {
var x = 1;

function qj2() {
var x = 'A';
console.log('inner' + x); // inner
}
qj2()
console.log('outer' + x); // outer
}

qj()

假设在JavaScript中函数查找变量从自身函数开始~

由“内”向“外”查找。 假设外部存在这个同名的函数变量,则内部函数的变量会屏蔽外部的变量

提升变量的作用域

1
2
3
4
5
function qj(){
var x = 'x' + y;
console.log(x);
var y = 'y';
}

结果:xundefined

说明:JS执行引擎,自动提升了y的声明,但不会提升变量y 的赋值;

1
2
3
4
5
6
7
function qj2(){
var y;

var x = 'x' + y;
console.log(x);
y = 'y';
}

这个是在JavaScript建立之初就存在的特性,所以养成规范,所有的变量定义都放在函数的头部,便于代码的维护

Js引擎会先定义所有的全局变量,然后按照顺序赋值

1
2
3
4
5
6
function qj2(){
var x = 1,
y = x + 1,
z, i, a; // undefined
//之后随意使用
}

全局函数

1
2
3
4
5
6
7
8
var x = 1;

function f() {
console.log(x)
}

f();
console.log(x)

全局对象 window

1
2
3
4
// 'use strict'
var x = 'xxxx';
alert(x);
alert(window.x) // 默认所有的全局变量,都会自动绑定在windows的对象下

alert()这个函数本身也是一个window的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
var x = 'xxxx';
window.alert(x);
var old_alert = window.alert;
window.alert = function () {

};

// 发现alert() 失效了
window.alert(123);

// 恢复
window.alert = old_alert();
window.alert(456);

javascript 实际上只有一个全局作用域,任何变量(函数也可以视为变量)假如没有在函数的作用域范围内找到,就会向外查找,如果在全局作用域都没有找到,报错 ReferenceError

规范

由于我们所有的全局变量都会绑定到我们的window上。如果不同的js文件,使用了相同的全局变量,冲突->如何能够减少冲突

1
2
3
4
5
6
7
8
// 唯一全局变量
var kuangApp = {};

// 定义全局变量
kuangApp.name = 'kuangshen';
kuangApp.add = function (a, b) {
return a + b;
}

把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突的问题~

jQuery

局部作用域 let

1
2
3
4
5
6
function aaa() {
for (var i = 0; i < 100; i++) {
console.log(i)
}
console.log(i + 1); // 问题? i 出了这个作用域还可以使用
}

ES6 let 关键字,解决局部作用域冲突问题!

1
2
3
4
5
6
function aaa() {
for (let i = 0; i < 100; i++) {
console.log(i)
}
console.log(i + 1); // Uncaught ReferenceError: i is not defined
}

建议使用let关键字去定义局部作用域的变量

常量 const

在ES6之前,我们定义常量:只有用全部大些字母命名的变量就是常量;建议不要修改这样的值

1
2
3
const PI = 3.14; // 只读变量,不可更改
console.log(PI);
PI = '123 // TypeError

方法

定义方法

方法就是把函数放在对象的里面,对象只有两个属性:属性和方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var kuangshen = {
name: 'qingjiang',
birth:'2020',
// 方法
age: function () {
// 今年-出生的年
var now = new Date().getFullYear();
return now - this.birth
}
}

// 属性
kuangshen.name
// 方法,一定要带()
kuangshen.age()

this. 代表什么?拆开上面的代码块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getAge() {
var now = new Date().getFullYear();
return now - this.birth
}

var kuangshen = {
name: 'qingjiang',
birth:'2020',
// 方法
age: getAge
};

// kuangshen.age() ok
// getAge() NaN window 对象

this是无法指向的,是默认指向调用他的那个对象

apply

在js中可以控制this的指向

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function getAge() {
var now = new Date().getFullYear();
return now - this.birth
}

var kuangshen = {
name: 'qingjiang',
birth:'2020',
// 方法
age: getAge
};

// kuangshen.age() ok
// getAge() NaN

// 这里在console里输入,直接运行会报错
getAge().apply(kuangshen, []); // this 只想了kuangshen这个对象,参数为空

内部对象

标准对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typeof 123
"number"
typeof '123'
"string"
typeof true
"boolean"
typeof NaN
"number"
typeof []
"object"
typeof {}
"object"
typeof Math.abs
"function"
typeof undefined
"undefined"

Date

基本使用

1
2
3
4
5
6
7
8
9
10
11
var now = new Date(); //Sun Apr 11 2021 10:07:57 GMT+0800 (中国标准时间)
now.getFullYear(); // 年
now.getMonth(); // 月 0——11
now.getDate();// 日
now.getDay();// 星期几
now.getHours(); // 时
now.getMinutes() //分
now.getSeconds() //秒
now.getTime(); // 时间戳 全世界统一 1970 1.1 0:00:00 毫秒数
console.log(new Date(now.getTime())) // console.log(new Date(now.getTime())) == console.log(new Date())

转换

1
2
3
4
5
6
7
8
now = new Date(now.getTime())
Sun Apr 11 2021 10:18:28 GMT+0800 (中国标准时间)

now.toLocaleDateString()
"2021/4/11"

now.toGMTString()
"Sun, 11 Apr 2021 02:18:28 GMT"

RegExp:正则表达式对象

正则表达式:定义字符串的组成规则。

  1. 单个字符:[]
        如: [a] [ab] [a-zA-Z0-9_]
    • 特殊符号代表特殊含义的单个字符:
          \d:单个数字字符 [0-9]
          \w:单个单词字符[a-zA-Z0-9_]
  2. 量词符号:
    ?:表示出现0次或1次
    *:表示出现0次或多次
    +:出现1次或多次
    {m,n}:表示 m<= 数量 <= n
    • m如果缺省: {,n}:最多n次
    • n如果缺省:{m,} 最少m次
  3. 开始结束符号
  • ^:开始
  • $:结束

正则对象:

  1. 创建
    1. var reg = new RegExp("正则表达式");
      var reg = /正则表达式/; //推荐使用这种用法
      
      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
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      2. 方法	

      1. test(参数):验证指定的字符串是否符合正则定义的规范



      ### Global

      1. 特点:全局对象,这个Global中封装的方法不需要对象就可以直接调用。 方法名();
      2. 方法:
      encodeURI():url编码
      decodeURI():url解码

      ​ encodeURIComponent():url编码,编码的字符更多
      ​ decodeURIComponent():url解码

      ​ parseInt():将字符串转为数字
      * 逐一判断每一个字符是否是数字,直到不是数字为止,将前边数字部分转为number
      isNaN():判断一个值是否是NaN
      * NaN六亲不认,连自己都不认。NaN参与的==比较全部问false

      ​ eval():讲 JavaScript 字符串,并把它作为脚本代码来执行。
      3. URL编码
      传智播客 = %E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2

      ```html
      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <title>Global对象</title>
      <script >

      /*

      Global
      1. 特点:全局对象,这个Global中封装的方法不需要对象就可以直接调用。 方法名();
      2. 方法:
      encodeURI():url编码
      decodeURI():url解码

      encodeURIComponent():url编码,编码的字符更多
      decodeURIComponent():url解码

      parseInt():将字符串转为数字
      * 逐一判断每一个字符是否是数字,直到不是数字为止,将前边数字部分转为number
      isNaN():判断一个值是否是NaN
      * NaN六亲不认,连自己都不认。NaN参与的==比较全部问false

      eval():讲 JavaScript 字符串,并把它作为脚本代码来执行。
      3. URL编码
      传智播客 = %E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2



      *
      */
      var str = "http://www.baidu.com?wd=传智播客";
      var encode = encodeURI(str);
      document.write(encode +"<br>");//%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2
      var s = decodeURI(encode);
      document.write(s +"<br>");//传智播客


      var str1 = "http://www.baidu.com?wd=传智播客";
      var encode1 = encodeURIComponent(str1);
      document.write(encode1 +"<br>");//%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2
      var s1 = decodeURIComponent(encode);
      document.write(s1 +"<br>");//传智播客


      var str = "a234abc";
      var number = parseInt(str);
      //alert(number + 1);

      var a = NaN;

      document.write(a == NaN);
      document.write(isNaN(a));

      var jscode = "alert(123)";
      eval(jscode);

      </script>
      </head>
      <body>

      </body>
      </html>

Json

json 是什么

早期,所有数据传输习惯使用XML文件

  • json 是一种轻量级的数据交换格式
  • 简洁和清晰的层次结构使得JSON成为理想的数据交换语言
  • 易于人阅读和编写,同时也易于机器解析和生成,并且有效的提升网络的传输效率

在javascript中一切皆为对象、任何js支持的类型都可以用json来表示number, String…

格式:

  • 对象都用{}
  • 数组都用[]
  • 所有的键值对 都是使用key:value

JSON字符串和JS对象的转换

1
2
3
4
5
6
7
8
9
10
11
var user = {
name: "yuxuan",
age: 3,
sex: "male"
};

// 对象转化为json字符串 {"name":"yuxuan","age":3,"sex":"male"}
var json_user = JSON.stringify(user);

// json 字符串转化为对象
var obj = JSON.parse('{"name":"yuxuan","age": 3,"sex": "male"}');

外面双,里面单,里面单外面双

很多人搞不清楚JSON和JS对象的区别

1
2
var obj = {a:'hello', b:'hellob'};
var json = '{"a":"hello", "b":"hellob"}';

Ajax

  • 原生的js写法,xhr异步请求
  • jQuery 封装好的方法 $(“#name”).ajax(“”)
  • axios 请求

面向对象编程

什么是面向对象

JavaScript,Java,c#。。。JavaScript有些区别

类:模版

对象:具体的实例

在JavaScript中需要转换一下思维

原型对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var user = {
name: "yuxuan",
age: 3,
sex: "male",
run: function () {
console.log(this.name+" run....")
}
};

var xiaoming = {
name: "xiaoming"
}
// 原型对象
xiaoming.__proto__ = user;
console.log(xiaoming.run())

class 继承

class关键字,是在ES6引入的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// ES6 之后 ============
// 定义一个学生的类
class Student{
constructor(name) {
this.name = name;
}
hello(){
alert('hello')
}
}

var xiaoming = new Student('xiaoming')
console.log(xiaoming.name)
console.log(xiaoming.hello())

2、继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// ES6 之后 ============
// 定义一个学生的类
class Student{
constructor(name) {
this.name = name;
}
hello(){
alert('hello')
}
}

class PrimaryStudents extends Student {
constructor(name,grade) {
super(name);
this.grade = grade
}

myGrade() {
alert('I am a primary student');
}
}

var xiaoming = new Student('xiaoming')
var xiaohong = new PrimaryStudents('xiaohong','100')

本质:查看对象原型

原型链

image-20210411114538259

操作BOM对象(重点)

浏览器介绍

Javascript 和浏览器的关系?

JavaScript诞生就是为了能够他在浏览器中运行

BOM:浏览器对象模型

  • IE 6~11
  • Chrome
  • Safari
  • FireFox

三方

  • QQ浏览器
  • 360浏览器

window

window代表浏览器窗口

1
2
3
4
5
6
7
8
9
10
11
window.alert(1)
undefined
window.innerHeight
766
window.innerWidth
393
window.outerHeight
877
window.outerWidth
958
// 大家可以调整浏览器窗口试试...

Navigator(不建议使用)

Navigator, 封装了浏览器的信息

1
2
3
4
5
6
7
8
navigator.appName
"Netscape"
navigator.appVersion
"5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
navigator.userAgent
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
navigator.platform
"MacIntel"

大多数的时候,我们不会使用navigator对象,因为会被人为修改!

不建议使用这些属性来判断和编写代码

screen

代表屏幕尺寸

1
2
3
4
screen.width
1440
screen.height
900

location (重要)

location 代表当前页面的URL信息

1
2
3
4
5
6
7

host: "new-tab-page"
href: "chrome://new-tab-page/"
protocol: "chrome:"
reload: ƒ reload() // 刷新网页
// 设置新的地址
location.assign("https://yuxuanwu17.github.io/")

Document (内容)

document 代表当前的页面,HTML DOM文档树

1
2
document.title
"百度一下,你就知道"

获取具体的文档树节点

1
2
3
4
5
<dl id="app">
<dt>Java</dt>
<dd>JavaSE</dd>
<dd>JavaEE</dd>
</dl>

获取cookie

1
2
document.cookie
""

劫持cookie的原理

www.taobao.com

1
2
<script src="aa.js"></script>
<!--恶意人员:获取你的cookie上传到他的服务器-->

服务器端可以设置cookie:httpOnly

history

History 代表浏览器的历史记录

1
2
3
4
history.back() // 后退

history.forward() //前进

操作DOM对象(重点)

DOM(Document Object Model):文档对象模型

核心

浏览器网页是一个DOM树形结构!

  • 更新:更新DOM节点
  • 遍历DOM节点:得到DOM节点
  • 删除:删除一个DOM节点
  • 添加:添加一个新的节点

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

DOM HTML tree

获得DOM节点

DOM 节点 (定义)

根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:

  • 整个文档是一个文档节点
  • 每个 HTML 元素是元素节点
  • HTML 元素内的文本是文本节点
  • 每个 HTML 属性是属性节点
  • 注释是注释节点

DOM可通过 JavaScript (以及其他编程语言)对 HTML DOM 进行访问。

所有 HTML 元素被定义为对象,而编程接口则是对象方法和对象属性。

方法是您能够执行的动作(比如添加或修改元素)。

属性是您能够获取或设置的值(比如节点的名称或内容)。

1
2
3
4
5
6
7
// 对应css选择器
var h1 = document.getElementsByTagName('h1');
var p1 = document.getElementById('p1');
var p2 = document.getElementsByClassName('p2');
var father = document.getElementById('father')

var children = father.children; // 获取父节点下的所有子节点

这是原生代码,之后我们尽量都是使用jQuery

更新节点

1
2
3
4
5
6
7
<div id="id1">
</div>

<script>
var id1 = document.getElementById('id1')

</script>

操作文本

  • id1.innerText="123"修改文本的值
  • id1.innerHTML = '<strong>123</strong>'可以解析HTML文本标签

操作JS

1
2
3
id1.style.color = 'red'; // 属性使用字符串包裹
id1.style.fontSize='20px'; // 驼峰命名
id1.style.padding = '2em';

删除节点

删除节点的步骤:先获取父节点,在通过父节点删除自己

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="father">
<h1>标题一</h1>
<p id = "p1">p1</p>
<p class = "p2">p2</p>
</div>
<script>
var self = document.getElementByID('p1');
var father = p1.parentElement;
father.removeChild(p1)


// 删除是一个动态的过程
father.removeChild(father.children[0])
father.removeChild(father.children[1])
father.removeChild(father.children[2])
</script>

注意:删除多个节点的时候,children是在时刻变化的,删除节点的时候一定要注意!

插入节点

我们获得了某个DOM节点,假设这个DOM节点是空的,我们通过innerHTML 就可以增加一个元素了,但是这个DOM节点已经存在元素了,我们就不能这么干了,会产生覆盖

追加操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<p id="js">
JavaScript
</p>

<div id="list">
<p id="se">JavaSE</p>
<p id="ee">JavaEE</p>
<p id="me">JavaME</p>
</div>

<script>
var js = document.getElementById('js');
var list = document.getElementById('list');

</script>

效果:

image-20210412104659016

创建一个新的标签,实现插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
var js = document.getElementById('js'); // 已经存在的节点
var list = document.getElementById('list');
// 通过js创造一个新的节点
var newP = document.createElement('p') // 创建一个新的p标签
newP.id = 'newP';
newP.innerText = 'Hello world';
// list.appendChild(newP)

// 创建一个标签节点
var myScript = document.createElement('script');
myScript.setAttribute('type', 'text/javascript');

// 可以创建一个Style标签
var myStyle = document.createElement('style'); // 创建了一个空的style标签
myStyle.setAttribute('type', 'text/css');
myStyle.innerHTML = 'body{background-color:chartreuse}'; //设置标签的内容
document.getElementsByTagName('head')[0].appendChild(myStyle)

</script>

操作表单(验证)

表单是什么 form DOM树

  • 文本框 text
  • 下拉框 <select>
  • 单选框 radio
  • 多选框 checkbox
  • 隐藏域 hidden
  • 密码框 password

表单的目的:提交信息

获得要提交的信息

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
<form action="post">
<p>
<span>用户名:</span>
<input type="text" id="username">
</p>

<!-- 多选框的值,就是定义好的value-->
<p>
<span>性别:</span>
<input type="radio" name="sex" value="man" id="boy">
<input type="radio" name="sex" value="female" id="girl">

</p>

</form>
<script>
var input_text = document.getElementById("username");
var input_man = document.getElementById("boy");
var input_female = document.getElementById("girl");

// 得到输入的值
input_text.value
// 修改输入的值
input_text.value = '123'

// 对于单选框,多选框等等固定的值,input_male 只能取到当前的值
input_man.checked; // 查看返回的结果是否是true,如果是true,则被选中~
input_female.checked = true; // 赋值


</script>

提交表单(MD5加密算法)

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
<!--表单提交事件
onsubmit = 绑定一个提交检测的函数,true和false
将这个结果返回给表单,使用onsubmit
-->

<form action="#" method="post">
<p>
<span>用户名:</span> <input type="text" id="username" name="username">
</p>
<p>
<span>密码:</span> <input type="password" id="password" name="password">
</p>
<!-- 绑定事件 onclick 被点击-->
<button type="submit" onclick="aaa()"> 提交 </button>
</form>

<script>
function aaa() {
var username = document.getElementById('username');
var password = document.getElementById('password');
// console.log(username.value);
console.log(password.value);
// password.value = '12312';

// 可以用MD5 算法来进行加密
password.value = md5(password.value)
// password.value = '*****';
console.log(password.value)
}
</script>
  • Post title:JavaScript 笔记
  • Post author:Yuxuan Wu
  • Create time:2021-04-07 04:59:22
  • Post link:yuxuanwu17.github.io2021/04/07/2021-04-07-JavaScript-笔记/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.