论JavaScript位于后端层面的必要性


JavaScript参考手册

JS与ECM的关系

 

JS基础

JS编写位置

  1. <script>JS代码</script>标签内

  2. <script src="外部JS文件路径"></script>外部引入JS文件

  3. <a href="javascript:console.log('Test')">超链接</a>不推荐使用HTML标签中写入

字面量 变量 标识符

概述

字面量:不可改变的值,比如:1 2 3 "String"

变量:变量可以用来保存字面量

标识符:在JS中所有可以由我们自主命名的,比如:变量名、函数名、属性名。

字面量

数据类型

在JS中一共有六种数据类型

  1. String 字符串

  2. Number 数值

  3. Boolean 布尔值

  4. Null 空值

  5. Undefined 未定义

  6. Object 对象

前五种属于基本数据类型、Object属于引用数据类型。

String

\转移字符可以输出关键字本身

 var a = "\\";

Number

JS中所有的数值都是Number类型包括整数和浮点数

如果出现下列这种情况,可以使用typeof判断类型

 var a ="123";
 var b = 123.01;
 console.log(a);
 console.log(b);
 console.log(typeof a);
 console.log(typeof b);
 
 // 控制台
 123
 123.01
 string
 number

Number有值范围,如果超过的最大值就显示Infinity表示正无穷

 console.log(Number.MAX_VALUE * Number.MAX_VALUE);
 
 // 控制台
 Infinity

使用非Number运算会显示NAN(Not a Number)但是类型仍然属于Number

 var a = "abc" * "def";
 console.log(a);
 console.log(typeof a);
 
 // 控制台
 NaN
 number

如果使用JS进行浮点运算,可能得到一个不准确的结果,虽然其它语言也有这个问题但是都有解决办法,而JS不好解决,所以尽量不要使用JS进行对精确度要求比较高的运算

Boolean

Boolean只有两个值:true,false

 var a = true;
 console.log(a)
 console.log(typeof a)
 
 // 控制台
 true
 boolean

Null

Null类型的值只有一个,就null,null这个值专门用来表示一个为空的对象。使用typeof返回类型为Object

Undefined

当变量没有初始化时为undefined

 var a;
 console.log(a);
 console.log(typeof a);
 
 
 // 控制台
 undefined
 undefined

强制类型转化

其它的数据类型转换为String

调用被转换数据类型的toString()方法或者使用String()函数,该方法不会影响到原变量,它会将转换的结果返回。

 var num = 123;
 console.log(num)
 console.log(typeof num);
 console.log(num.toString())
 console.log(typeof num.toString())
 
 var num = 123;
 console.log(num)
 console.log(typeof num);
 num = String(num);
 console.log(num)
 console.log(typeof num);
 
 // 控制台
 123
 number
 123
 string

这两方法不同的地方在于Null和Undefined不能调用toString()方法转化但是String()方法可以

 var a = null;
 console.log(a.toString());
 console.log(typeof a);
 var b = undefined;
 console.log(b.toString());
 console.log(typeof b);
 
 // 控制台
 Uncaught TypeError: Cannot read properties of null (reading 'toString')
 
 
 var c = null;
 c = String(c);
 console.log(c);
 console.log(typeof c);
 var d = undefined;
 d = String(d);
 console.log(d);
 console.log(typeof d);
 
 // 控制台
 null
 string
 undefined
 string

将其它数据类型转换为Number

使用Number()函数

  1. String类型转换:如果字符串为数字那么就可以正常转换(空字符串或全为空格·转换为0),如果为非数字那么就转换为NaN

  2. Boolean类型转换:true为1,false为0

  3. Null类型转换:0

  4. undefined转换为NaN

var a = "123";
console.log(a);
console.log(typeof a);
a = Number(a);
console.log(a);
console.log(typeof a);

// 控制台
123.01
string
123.01
number

var a = "abc";
a = Number(a);
console.log(a);
console.log(typeof a);

// 控制台
NaN
number

var a = " ";
a = Number(a);
console.log(a);
console.log(typeof a);

// 控制台
0
number

该方法只针对String

如果对非String使用pareInt()或parseFloat()它会先将其转换为String

  • parseInt()函数 可以将一个字符串中第一个非数字之前整数内容提起出来转换为Number

    var a = "123a456px";
    a = parseInt(a);
    console.log(a);
    console.log(typeof a);

    // 控制台
    123
    number

    var a = "a123bc";
    a = parseInt(a);
    console.log(a);
    console.log(typeof a);

    // 控制台
    NaN
    number
  • parseFloat()函数转换为浮点数

    var a = "12.01.1px";
    a = parseInt(a);
    console.log(a);
    console.log(typeof a);

    // 控制台
    12.01
    number

其它进制的数字

<!--如果要表示16进制的数字,则需要以0x开头-->
var a = 0x10;
console.log(a);
<!--如果要表示8进制的数字,则需要以0o开头-->
a = 0o10;
console.log(a);
<!--如果要表示2进制的数字,则需要以0b开头-->
a = 0b10;
console.log(a);

// 浏览器根据不同的版本转换的结果也不同

其他数据类型转换为Boolean

  1. Number类型,0、NaN为false,非0、Infinity、Undefined为true

  2. String类型,非空串为true

  3. Null和Undefined为false

var a = 11;
console.log(a);
console.log(typeof a);
a = Boolean(a);
console.log(a);
console.log(typeof a);

// 控制台
11
number
true
boolean

操作符

算数运算符

运算符也叫操作符,通过运算符可以对一个或多个值进行运算,并获取运算结果

+ String>Number>(Boolean,Null,Undefined)按照以上优先级运算,字符串+视为拼接操作运算顺序:从左往右

-

*

/ 不同于Java整除JS中/符合人类规则

%

除了+特殊其余都是转换为Number再进行计算

一元运算符

typeof 获得一个值的类型并且以字符串的形式返回

+ 正号

- 负号

对于非Number类型的值会将其转换为Number然后运算

自增和自减

++

--

逻辑运算符

其它数据类型转换为Boolean再进行运算

!

&&

||

输出Unicode编码表中字符

\u四位Unicode编码

相等运算符

除了个别用例基本保持 转换为Number再比较

NaN和任何值都不相等,所以只能使用isNaN()函数来判断是否为NaN

console.log(undefined == null); // true

console.log(0 == null); // false

===全等不会做类型转换

!==

对象 Object

对象的分类

  1. 内建对象:

    • 由ES标准中定义的对象,在任何的ES实现中都可以使用 比如:Math、String、Number、Boolean

  2. 宿主对象:

    • 由JS的运行环境提供的对象,目前来讲主要指由浏览器浏览器提供的对象 比如:BOM DOM

  3. 自定义对象:

    • 由开发人员自定义

    var obj = new Object();
    // 在对象中保存属性 语法:对象.属性名 = 属性值
    obj.name = "ccy";
    obj.age = 22;
    obj.gender = "男";
    // 删除对象属性
    delete obj.name;
    // 如果要使用特殊的属性名,需要使用另一种方式 语法:对象["属性名"] = 属性值
    obj["123"] = 789;
    // []中也可以放入变量!!!
    var n = "123";
    console.log(obj[n]); // 789

    对象的属性不仅可以包含基本数据类型而且还包括对象本身

    var obj1 = new Object();
    var obj2 = new Object();
    obj1.name = "ccy";
    obj1.age = 22;
    obj2.country = "中国";
    obj2.address = "山西";
    obj1.info = obj2;
    /**
    * in运算符
    * - 通过该运算符可以检查该对象中是否含有指定属性,返回类型为Boolean
    * - 语法:"属性名" in 对象
    */
    console.log("info" in obj1);
    console.log("test" in obj1);

    除了var ojb = new Object()构造方法创建对象以外还有一种声明方式使用方便

    var obj = {
    name: "ccy",
    age: 22,
    isStudent: true
    };
    console.log(obj);

方法

对象的属性可以是任意数据类型,所以也包括函数,当函数作为对象属性时又称作:方法

var obj = {
name: "ccy",
age: 22,
gender: "男"
};

function fun() {
console.log(obj.name);
};
obj.info = fun;
obj.info();

// 控制台
ccy

枚举对象属性

var obj = {
name: "ccy",
age: 22,
gender: "男",
};
for (var n in obj) {
// 这句代码的含义是得到obj属性n的属性值
// console.log(obj.n);
// 对象[变量] 的一个好处就是可以放变量
console.log(n);
console.log(obj[n]);
}

函数 Function

创建函数

函数属于对象具有对象的功能

使用构造方法创建函数

// 可以将封装的代码以字符串的形式传递给构造函数
var fun = new Function("console.log('我是Ccy');");
console.log(typeof fun); // function 也属于 object
// 封装到函数中的代码不会立即执行,当调用函数时执行 语法:函数名()
fun();
fun();

使用声明方式创建函数

function fun(a, b) {
return a > b ? a : b;
}

console.log(fun(2, 4));

使用函数表达式来创建函数

var fun = function (a, b) {
return a > b ? a : b;
}

参数

  1. 调用函数时解析器不会检查实参的类型,所以要注意,可能会接受到非法的参数

  2. 调用函数时解析器不会检查实参的数量,多余的实参不会被赋值

var fun = function (a, b) {
console.log(a + b);
}
// 不会检查实参类型
fun(123, 456); // 579
fun("123", 456); // 123456
fun(true, false); // 1
// 不会检查实参的数量
fun(123, 456, "789", true); // 579
fun(123); // NaN 如果实参数量少于形参的数量,那么没有对应实参的形参数据类型为undefined
  1. 对象和函数都可以作为实参传入

function info(obj) {
console.log("My Name is " + obj.name +
".Tody,i am " + obj.age + " years old");
}
var obj = {
name : "ccy",
age : 22
};
info(obj);

function outer(a) {
console.log("我是outer " + a);
};

function inner(a) {
console.log("我是inner " + a);
return "zfs";
};

/**
* inner 属于函数对象,相当于直接使用函数对象
* inner() 属于调用函数,相当于使用函数的返回值
*/
outer(inner);
outer(inner("ccy"));

// 控制台
我是outer function inner(a) {
console.log("我是inner " + a);
return "zfs";
}
我是inner ccy
我是outer zfs

立即执行函数

声明匿名函数是不被允许的因为毫无意义,所以需要将匿名函数用()包裹起来看做整体随后调用

 /**
  * 立即执行函数:
  * 1. 函数定义完就可以立即执行
  * 2. 立即执行函数只能执行一次
  */
 (function (a, b) {
     console.log("a = " + a);
     console.log("b = " + b);
 })(2, 3);

作用域

作用域是指变量作用的范围

在JS中一共有两种作用域:全局作用域,函数作用域

在函数作用域中有声明前提的特征:

  • 使用var关键字声明的变量,会在函数中所有代码执行之前被声明

  console.log(a);
  var a = 10;
 
  // 控制台
  undefined
 
 console.log(a);
 a = 10;
 
 // 控制台
 Uncaught ReferenceError: a is not defined
  • 函数声明也会在代码执行之前执行,函数表达式则不会

fun1();
fun2();

function fun1() {
console.log("fun1");
};
var fun2 = function () {
console.log("fun2");
};

// 控制台
fun1
Uncaught TypeError: fun2 is not a function

全局作用域

  • 直接编写在<script>标签中的JS代码,都是在全局作用域中

  • 全局作用域在页面打开时创建,在页面关闭时销毁

  • 在全局作用域中有一个全局对象window,它代表的是一个浏览器的窗口

  • 在全局作用域中,创建的变量都会作为window对象的属性保存,创建的函数都会作为方法保存

函数作用域

  • 调用函数时创建函数作用域,函数执行完毕后函数作用域销毁

  • 每调用一次函数就会创建一个新的函数作用域,函数作用域之间相互独立

  • 在函数作用域中可以访问到全局作用域

  • 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果自身作用域找不到会到上一级寻找。在函数中不使用var声明的变量都会成为全局变量

    var a = 123;

    function fun() {
    var a = 567;
    console.log(a);
    }
    window.fun();

this

/**
* 解析器在调用函数每次都会向函数内部传递一个隐含参数
* 这个隐含的参数就是this,this指向的是一个对象
* 这个对象我们称为函数执行的上下文对象,根据函数调用方式的不同,this会指向不同的对象
* 1. 以函数的形式调用时,this为window
* 2. 以方法的形式调用时,this为调用方法的Object
* 3. 以构造函数调用时,this为实例
* 4. 使用call()和apply调用时,this是传入对象
*/
function fun() {
console.log(this);
};
fun();
// 创建对象
var obj = {
name: "ccy",
age: 22,
sayThis: fun
};
obj.sayThis();

 

call()和apply()

function fun(a, b) {
console.log(this);
console.log(this.name);
console.log("a = " + a);
console.log("b = " + b);
};
var obj1 = {
name: "ccy"
};
var obj12 = {
name: "zfs"
};
/**
* 当函数调用call()和apply()都会执行函数
* 在调用这两个方法时可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时this
* call()方法可以将实参在对象之后传递
* apply()方法需要将实参封装到一个数组中统一传递
*/
fun.call(obj1, 2, 3);
fun.apply(obj12, [2, 3]);

 

arguments

/**
* 在调用函数时,浏览器每次都会传递两个隐含的参数
* 1. 函数上下文对象 this
* 2. 封装实参的对象 arguments
* - arguments是"类数组"对象,可以通过索引操作数据也可以获取长度(arguments.length)
* - 传入函数的实参都会保留在arguments
* - 即使不定义形参,也可以通过arguments使用传入实参(不推荐使用)
* - arguments.callee对应函数对象本身
*/
function fun() {
console.log(arguments.length);
console.log("a = " + arguments[0]);
console.log("b = " + arguments[1]);
console.log(arguments.callee); // fun
};
fun(1, 2);

 

构造函数

/**
* 因为所有的对象的数据类型都是Object所以为了区分创建构造函数
* 构造函数就是普通函数,创建方式和普通函数没有区别,唯一的不同在于构造函数的函数名习惯上首字母大写
*
* 构造函数和普通函数的区别就是调用方式不能,普通函数是直接调用,而构造函数需要使用new关键字来调用
*
* 构造函数的执行流程
* 1. 立刻创建一个新对象
* 2. 将新建对象设置为函数中的this
* 3. 逐行执行函数代码
* 4. 将新建对象作为返回值返回
*/
function Person() {
this.name = "ccy";
this.age = 22;
this.address = "山西省";
};

function Dog() {
this.name = "柯基";
this.age = 4;
this.operation = "吃骨头";
};

var person = new Person();
var dog = new Dog();
console.log(person);
console.log(dog);

 

/**
* instanceof检查一个对象是否是一个类的实例
* 语法: 对象 instanceof 构造函数
* 如果是则返回true否则返回false
*/
console.log(person instanceof Person);
console.log(dog instanceof Dog);

// 控制台
true
true
function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = function () {
console.log("this.name = " + this.name);
}
};
var person1 = new Person("ccy", 22);
var person2 = new Person("zfs", 18);
/**
* 构造函数内部创建方法,每调用一次构造函数就会创建一个新的sayName方法,也就是说所有实例的sayName方法都是唯一的
* 但是这完全没必要,完全可以使所有对象共享一个方法
*/
console.log(person1.sayName == person2.sayName); // false

为了使得实例方法不必要的创建,对构造方法做出改良。但此方法的弊端就是将函数定义在全局作用域中,污染了全局作用域的命名空间。而且定义在全局作用域中不安全。

function Person(name, age) {
this.name = name;
this.age = age;
this.sayName = fun
};

function fun() {
console.log("this.name = " + this.name);
};

var person1 = new Person("ccy", 22);
var person2 = new Person("zfs", 18);
console.log(person1.sayName == person2.sayName); // true

原型对象

以后创建构造函数时,可以将这些对象共有的属性和方法统一添加到构造函数的原型对象中

/**
* 我们所创建的每一个函数,解析器都会向解析其中添加一个属性:prototype(原型对象)
* 当函数作为普通函数调用prototype没有任何作用
* 当函数作为构造函数调用,它所创建的对象中都会含有一个属性指向该构造函数的原型对象,我们可以通过__proto__来访问
*/
function Person() {

};
console.log("prototype" in Person); // true
var person = new Person();
console.log(Person.prototype);
console.log(person.__proto__);
/**
* 原型对象就相当于一个公共区域,所有同类的实例都可以访问到这个原型对象,可以将对象中共有的内容统一设置到原型对象中
*/
Person.prototype.a = "ccy";
console.log(person.a);

 

function Person() {

};
Person.prototype.name = "ccy";
var person = new Person();
// 使用in检查对象中是否含有某个属性时,如果对象中没有但是原型对象中有则也会返回true
console.log("name" in person); // true
// 使用hasOwnProperty()检查对象自身是否含有该属性
console.log(person.hasOwnProperty("name")); // false

原型对象也是对象,所以它也有原型对象,当我们使用一个对象的属性或方法时会先在自身中寻找。

自身中如果有则直接使用。

如果自身中没有则回去原型对象中寻找,如果原型对象中也没有则会去原型对象的原型对象中寻找,此时若还没有找到则返回undefined

 

toString()

function Person(name, age, gender) {
this.name = name;
this.age = age;
this.age = gender;
};
var person = new Person("ccy", 22, "男");
console.log(person.toString()); // [object Object]
console.log(person.__proto__.__proto__.hasOwnProperty("toString")); // true

数组

构造数组一共有三种方法

// 1. 构造函数数组
var array1 = new Array();
// 2. 构造函数数组,构造数组长度为10的数组
var array2 = new Array(10);
// 3. 声明数组
var array3 = [1, 2, 3, 4, "ccy", 6];

创建数组的方式

// 构造方法创建数组对象
var array = new Array();
// 向数组中添加元素 语法:数组[索引] = 值
array[0] = 10;
array[1] = 20;
array[2] = 20;
// 非连续数组
array[5] = 50;
// 读取数组中元素 语法:数组[索引]
console.log(array[1]); // 20
/**
* 对于连续的数组,使用length设置或返回数组中元素的数量
* 对于非连续的数组,使用length返回数组最大索引值+1
*/
console.log(array.length); // 6

如果修改length大于原长度,多余的索引位置会空出

如果修改length小于原长度,多余的索引位置会删除

var array = new Array();
array[0] = 10;
array[1] = 20;
array[2] = 20;
array.length = 10;
console.log(array);
array.length = 1;
console.log(array);

 

数组的增删方法

push()

该方法向数组的末尾添加一个或多个元素,并返回数组的新长度

var array = new Array();
console.log(array.push(1, 2, 3, 4, 5, 6, 7)); // 7
console.log(array); // [1, 2, 3, 4, 5, 6, 7]

pop()

该方法可以删除数组的末尾元素,并将删除元素返回

var array = [1, 2, 3, 4, 5, 6];
console.log(array);
console.log(array.pop());
console.log(array);

 

unshift()

该方法向数组的开头添加一个或多个元素,并返回数组的新长度

var array = new Array();
array.unshift(1, 2, 3);
array.unshift(4, 5, 6);
console.log(array); // [4, 5, 6, 1, 2, 3]

shift()

该方法可以删除数组的开头元素,并将删除元素返回

var array = [1, 2, 3, 4, 5];
console.log(array.shift()); // 1
console.log(array); // [2, 3, 4, 5]

遍历数组

一般我们都是使用for循环遍历数组,JS中还为我们提供了一个方法用来遍历数组

foreach()

 var array = [1, 2, 3, 4, 5];
 /**
  *
  * @param value 当前遍历元素
  * @param index 当前遍历元素索引
  * @param array1 数组
  */
 array.forEach(function (value, index, array1) {
 
 })

数组其它方法

slice()

从某数组中返回选定的元素并以数组的形式返回,可以用于得到指定范围的数组元素

 var array = [1, 2, 3, 4, 5];
 /**
  * 该方法不会改变元素数组,而是将截取到的元素封装到一个新数组中返回和java中的split相似
  * @param 起始位置
  * @param 结束位置
  */
 var result = array.slice(0, 2);
 console.log(array); // [1, 2, 3, 4, 5]
 console.log(result); // [1, 2]

splice()

不同于slice()的是该方法会改变原数组,可以用于删除指定范围数组中元素,还可以替换被删除元素

 var array = [1, 2, 3, 4, 5];
 /**
  * 该方法会改变元素数组,而是将截取到的元素封装到一个新数组中返回
  * @param 起始位置
  * @param 删除数量
  * @param 替换元素们!
  */
 var result = array.splice(1, 1, 0, 0, 0);
 console.log(array); // [1, 0, 0, 0, 3, 4, 5]
 console.log(result); // [2]

concat()

可以连接两个或多个数组,并将新的数组返回,该方法不会对原数组产生影响

 var array1 = [1, 2, 3, 4, 5];
 var array2 = [6, 7, 8, 9, 10];
 var array3 = [11, 12, 13, 14, 15];
 var numbers = array1.concat(array2, array3, 16, 17);
 console.log(numbers) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]

join()

将数组中所有元素放入放入一个字符串。元素通过指定的分隔符进行分割,默认分隔符为","

 var array1 = [1, 2, 3, 4, 5];
 var s = array1.join(",");
 console.log(s); // 1,2,3,4,5

reverse()

改变原数组,反转数组

 var array1 = [1, 2, 3, 4, 5];
 var array2 = array1.reverse();
 console.log(array1); // [5, 4, 3, 2, 1]
 console.log(array2); // [5, 4, 3, 2, 1]

sort()

改变原数组,默认按升序排序,可以自定义排序规则

 var array1 = [1, 4, 2, 3, 7, 6, 5];
 var array2 = array1.sort();
 console.log(array1); // [1, 2, 3, 4, 5, 6, 7]
 console.log(array2); // [1, 2, 3, 4, 5, 6, 7]
 
 
 var array1 = [1, 4, 2, 3, 7, 6, 5];
 /**
  * 添加回调函数,自定义排序规则
  * 浏览器会根据回调函数的返回值来决定元素的顺序,如果返回一个大于0的值,元素会交换位置
  * @param 索引值较大元素
  * @param 索引值较小元素
  */
 array1.sort(function (a, b) {
     return b - a;
 });
 console.log(array1); // [7, 6, 5, 4, 3, 2, 1]

Date

 // 使用构造函数创建Date对象,则表示执行这行代码的时间
 var date1 = new Date();
 console.log(date1);
 // 使用构造函数传递参数创建指定时间
 // 日期格式:月/日/年 时:分:秒
 var date2 = new Date("3/25/2001 22:30:18");
 console.log(date2);
 // getDate():获得一个月中的某一天
 var date = date1.getDate();
 console.log(date);
 // getDay():获得一周中的某一天 (星期日-星期六):(0-6)
 var day = date1.getDay();
 console.log(day);
 // getMonth():获取月份 (一月-十二月):(0-11)
 var month = date1.getMonth();
 console.log(month);
 // getTime():获取格林威治时间(我们位于东八区和此有8小时时差)1970年1月1日 0时0分0秒到当前日期所花费的毫秒数
 var time = date1.getTime();
 console.log(time);
 // 获取当前时间戳
 console.log(Date.now());

 

Math

 

 // Math:Math和其他对象不同,他不是一个构造函数
 console.log(typeof Math); // object
 // abs() 绝对值
 console.log(Math.abs(-1)) // 1
 // ceil() 向上取整
 console.log(Math.ceil(1.5)) // 2
 // floor() 向下取整
 console.log(Math.floor(1.5)) // 1
 // round() 四舍五入
 console.log(Math.round(1.4)) // 1
 // random() 获取(0,1)之间的随机数
 console.log(Math.random())
 // 获取[1,10]之间的随机数
 console.log(Math.ceil(Math.random() * 9) + 1);

包装类

基本数据类型 String Number Boolean Null Undefined不是对象功能没有那么强大,我们知道基本数据类型不能够像对象一样拥有属性和方法但是在调用基本数据类型时为什么会有原生属性和方法呢?

 var str = "zfs ccy";
 str.name = "ss"
 console.log(str.name); // undefined

 

重点讲解String

 var str = "ccy zfs";
 // charAt() 返回索引位置的字符
 var char = str.charAt(2);
 console.log(char);
 // charCodeAt() 返回索引位置的字符的Unicode编码
 var code = str.charCodeAt(2);
 console.log(code);
 // fromCharCode() 返回Unicode编码的字符
 char = String.fromCharCode(65);
 console.log(char);
 // indexOf() 返回检索字符首次(默认第二个参数为0,可以选择)出现的索引值,如果没有检索到指定字符那么就返回-1
 var flag = str.indexOf("c", 1); // 1
 console.log(flag);
 // split() 将字符串拆分为数组
 var array = str.split(" ");
 array.forEach(function (value) {
     console.log(value);
 });

正则表达式

创建正则表达式

 /**
  * 构造方法创建正则表达式 new RegExp("正则表达式","匹配模式");
  * 匹配模式:i 忽略大小写 g 全局匹配
  */
 var reg = new RegExp("a");
 var str = "a";
 var flag = reg.test(str);
 console.log(flag); // true
 
 /**
  * 使用字面量来创建正则表达式 /正则表达式/匹配模式
  */
 var reg = /a/;
 

DOM

查询DOM

获取元素节点

通过document对象调用

  1. getElementById() 通过id属性获取一个元素节点对象

  2. getElementsByTagName()通过标签名获取一组元素节点对象(返回类数组对象)

  3. getElementsByName()通过name属性获取一组元素节点对象

由于JS代码的执行的特点,JS代码要不位于HTML后写,要不放入window.onload = function () {}

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <script>
         // 由于JS代码的运行机制是一行一行执行,所以当JS代码加载时但HTML代码还未加载完成导致JS代码未生效,window.onload可以确保页面加载完成以后再运行代码
         window.onload = function () {
             document.getElementById("btn").onclick = function () {
                 console.log("ccy");
            };
        };
     </script>
 </head>
 <body>
     <button id="btn">按钮</button>
 </body>
 </html>

图片切换的操作

图片切换的原理在于更改src属性

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <script>
         var count = 1;
         window.onload = function () {
             document.getElementById("prev").onclick = function () {
                 if (count == 1) {
                     alert("已经到开头辣");
                } else {
                     document.getElementById("img").src = "img/" + (--count) + ".jpg";
                }
            };
             document.getElementById("next").onclick = function () {
                 if (count == 4) {
                     alert("已经到结尾辣");
                } else {
                     document.getElementById("img").src = "img/" + ++count + ".jpg";
                }
            };
        };
     </script>
 </head>
 <body>
     <div id="outer">
         <img id="img" src="img/1.jpg">
         <button id="prev">上一张</button>
         <button id="next">下一张</button>
     </div>
 </body>
 </html>

获取元素节点的子节点

通过具体的元素节点调用

  1. getElementsByTagName()方法:返回当前节点的指定标签名后代节点

  2. childNodes属性:表示当前节点的所有子节点 获取包括文本节点在内的所有节点,DOM标签间空白也会被当成文本,这点不同于children

  3. firstChild属性:表示当前节点的第一个子节点

  4. lastChild

获取父节点和兄弟节点

通过具体的元素节点调用

  1. parentNode属性:表示当前节点的父节点

  2. previousSibling属性:表示当前节点的前一个兄弟节点

  3. nextSibling属性:表示当前节点的后一个兄弟节点

全选操作

全选操作的原理是更改复选框checked属性

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <script>
         window.onload = function () {
             var items = document.getElementsByName("items");
 
             // 判断全选和不全选状态
             function f() {
                 var checkedAllBox = document.getElementById("checkedAllBox");
                 var count = 0;
                 for (var i = 0; i < items.length; i++) {
                     if (items[i].checked == true) {
                         count++;
                    }
                }
                 if (count == items.length) {
                     checkedAllBox.checked = true;
                } else {
                     checkedAllBox.checked = false;
                }
            };
 
             // 设置全选
             document.getElementById("checkedAllBtn").onclick = function () {
                 for (var i = 0; i < items.length; i++) {
                     items[i].checked = true;
                }
                ;
                 f();
            };
             // 设置全不选
             document.getElementById("checkedNoBtn").onclick = function () {
                 for (var i = 0; i < items.length; i++) {
                     items[i].checked = false;
                }
                 f();
            };
             // 设置反选
             document.getElementById("checkedRevBtn").onclick = function () {
                 for (var i = 0; i < items.length; i++) {
                     items[i].checked = !items[i].checked;
                }
                 f();
            };
             // 为每个按钮绑定
             for (var i = 0; i < items.length; i++) {
                 items[i].onclick = function () {
                     f();
                }
            }
        }
     </script>
 </head>
 <body>
     <form method="post" action="">
         <input type="checkbox" id="checkedAllBox" disabled>全选/全不选<br>
         <input type="checkbox" name="items">足球
         <input type="checkbox" name="items">篮球
         <input type="checkbox" name="items">羽毛球
         <input type="checkbox" name="items">乒乓球<br>
         <button type="button" id="checkedAllBtn">全选</button>
         <button type="button" id="checkedNoBtn">全不选</button>
         <button type="button" id="checkedRevBtn">反选</button>
         <button type="button" id="sendBtn">提交</button>
     </form>
 </body>
 </html>

增删改DOM

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <script>
         window.onload = function () {
             /**
              * 添加山西节点到末尾
              *
              * createElement("元素节点标签") 创建元素节点
              * createTextNode("文本内容") 创建文本节点
              * appendChild() 向父节点中添加子节点到末尾
              */
             document.getElementById("btn01").onclick = function () {
                 // 创建元素节点
                 var li = document.createElement("li");
                 // 创建文本节点
                 var text = document.createTextNode("山西");
                 // 向父节点中添加子节点
                 li.appendChild(text);
                 // 将元素节点添加
                 var ul = document.getElementById("city");
                 ul.appendChild(li);
            };
             /**
              * 添加甘肃节点到开头
              * insertBefore(newNode, oldNode) 添加子节点到某节点之前
              */
             document.getElementById("btn02").onclick = function () {
                 // 创建元素节点
                 var li = document.createElement("li");
                 // 创建文本节点
                 var text = document.createTextNode("甘肃");
                 // 向父节点中添加子节点
                 li.appendChild(text);
                 // 添加到子节点前
                 var ul = document.getElementById("city");
                 var bj = document.getElementById("bj");
                 ul.insertBefore(li, bj);
            };
             /**
              * 替换深圳节点为东北节点
              * replaceChild(newNode, oldNode) 替换节点
              */
             document.getElementById("btn03").onclick = function () {
                 // 创建元素节点
                 var li = document.createElement("li");
                 // 创建文本节点
                 var text = document.createTextNode("东北");
                 // 向父节点中添加子节点
                 li.appendChild(text);
                 // 替换元素节点
                 var ul = document.getElementById("city");
                 var sz = document.getElementById("sz");
                 ul.replaceChild(li, sz);
            };
             /**
              * 删除上海节点
              */
             document.getElementById("btn04").onclick = function () {
                 // var ul = document.getElementById("city");
                 // var sh = document.getElementById("sh");
                 // ul.removeChild(sh);
                 // 不同获取父节点删除节点 常用
                 var sh = document.getElementById("sh");
                 sh.parentNode.removeChild(sh);
            };
        }
     </script>
 </head>
 <body>
     <div id="total">
         <div class="inner">
             <p>你喜欢哪座城市?</p>
         </div>
         <ul id="city">
             <li id="bj">北京</li>
             <li id="sh">上海</li>
             <li id="gd">广东</li>
             <li id="sz">深圳</li>
         </ul>
     </div>
     <button id="btn01">添加山西节点到末尾</button>
     <button id="btn02">添加甘肃节点到开头</button>
     <button id="btn03">替换深圳节点为东北节点</button>
     <button id="btn04">删除上海节点</button>
 </body>
 </html>

操作CSS

操作内联样式

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <style>
         #box {
             width: 200px;
             height: 200px;
             background-color: red;
        }
     </style>
     <script>
         window.onload = function () {
             /**
              * 通过JS修改元素的央视 语法:元素.style.样式名 = 样式值
              * 修改元素的内联样式,由于内联样式的优先级高所以会覆盖
              */
             var box = document.getElementById("box");
             box.onclick = function () {
                 box.style.backgroundColor = "blue";
            };
 
             // 获取到的是内联样式
             document.getElementById("btn").onclick = function () {
                 // 第一次为空原因是此时元素节点内联样式为空
                 alert(box.style.backgroundColor);
            }
        };
     </script>
 </head>
 <body>
     <div id="box">
     </div>
     <button id="btn">获取CSS</button>
 </body>
 </html>

 

获取当前样式

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <style>
         #box {
             width: 100px;
             height: 100px;
             background-color: yellow;
        }
     </style>
     <script>
         window.onload = function () {
             var box = document.getElementById("box");
             box.onclick = function () {
                 box.style.backgroundColor = "blue";
            };
 
             document.getElementById("btn").onclick = function () {
                 // 只有IE8浏览器兼容
                 // alert(box.currentStyle.backgroundColor);
                 /**
                  * getComputedStyle()获取元素当前样式,这个方法是window的方法可以直接使用。读取到的样式是只读的
                  * @param 元素节点
                  * @param 伪元素一般为null
                  * @return 该方法会返回一个对象,对象中封装了当前元素对应的样式
                  */
                 alert(getComputedStyle(box, null).width);
            }
        };
     </script>
 </head>
 <body>
     <div id="box">
     </div>
     <button id="btn">获取CSS</button>
 </body>
 </html>

事件对象

显示鼠标坐标

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <style>
         #areaDiv {
             height: 200px;
             width: 400px;
             padding: 5px;
             background-color: yellow;
             margin: auto;
        }
 
         #showDiv {
             width: 200px;
             border: 3px solid green;
             margin: auto;
             padding: 70px 0;
             border: 3px solid green;
             text-align: center;
        }
     </style>
     <script>
         window.onload = function () {
             /**
              * onmousemove:该事件将会在鼠标在元素节点中移动时触发
              *
              * 事件对象:当时间的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递给响应函数
              * 事件对象中封装了当前事件的信息
              *
              */
             document.getElementById("areaDiv").onmousemove = function (event) {
                 var showDiv = document.getElementById("showDiv");
                 showDiv.innerText = "x = " + event.clientX + " y = " + event.clientY;
            }
        }
     </script>
 </head>
 <body>
     <div id="areaDiv"></div>
     <div id="showDiv"></div>
 </body>
 </html>

div跟随鼠标移动

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <style>
         #areaDiv {
             height: 200px;
             width: 200px;
             background-color: yellow;
             /*开启绝对定位*/
             position: absolute;
        }
     </style>
     <script>
         window.onload = function () {
             var areaDiv = document.getElementById("areaDiv");
             document.onmousemove = function (event) {
                 /**
                  * clientX和clientY是鼠标在可见窗口的相对坐标而div的偏移量是绝对的所以会出现bug
                  * pageX和pageY是相对于当前页面
                  */
                 var clientX = event.pageX;
                 var clientY = event.pageY;
                 // 设置div的css样式
                 areaDiv.style.left = clientX + "px";
                 areaDiv.style.top = clientY + "px";
            }
        }
     </script>
 </head>
 <body>
     <div id="areaDiv"></div>
 </body>
 </html>

事件冒泡

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <style>
         #div {
             height: 100px;
             width: 200px;
             background-color: yellow;
        }
 
         #span {
             height: 50px;
             width: 50px;
             background-color: lawngreen;
        }
     </style>
     <script>
         window.onload = function () {
             /**
              * 事件的冒泡:所谓的冒泡就是事件的向上传到,当后代元素上的事件被触发时,其祖先元素的享同事件也会被触发
              */
             document.getElementById("span").onclick = function (event) {
                 alert("I am Span");
                 // 将事件对象的cancelBubble设置为true可以取消冒泡
                 event.cancelBubble = true;
            }
             document.getElementById("div").onclick = function () {
                 alert("I am Div");
            }
             document.body.onclick = function () {
                 alert("I am Body");
            }
        }
     </script>
 </head>
 <body>
     <div id="div">
         <span id="span">我是Span</span>
         <p>我是Div</p>
     </div>
 </body>
 </html>

事件委派

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <script>
         window.onload = function () {
             var allA = document.getElementsByTagName("li");
             var length = allA.length;
             /**
              * 还记得我们之前做员工表格练习时的问题吗?每次新添加元素节点都需要绑定响应函数
              * 可以通过事件冒泡来解决,直接给父类元素节点绑定响应事件
              */
             document.getElementById("btn").onclick = function () {
                 var ul = document.getElementById("ul");
                 var li = document.createElement("li");
                 var a = document.createElement("a");
                 a.href = "javascript:;";
                 a.className = "link";
                 var text = document.createTextNode("链接" + ++length);
                 a.appendChild(text);
                 li.appendChild(a);
                 ul.appendChild(li);
            }
             /**
              * 我们希望,只绑定一次事件即可应用到多个元素上,即使元素是后添加的
              *
              * 事件委派:将事件统一绑定给元素的共同的祖先元素这样当子元素上的事件触发时,会因为事件冒泡到父元素
              */
             document.getElementById("ul").onclick = function (event) {
                 // 如果触发事件的元素是我们期望的元素对象那么就执行
                 if (event.target.className == "link") {
                     alert("123");
                }
            }
        }
     </script>
 </head>
 <body>
     <button id="btn">按钮</button>
     <ul id="ul" style="background: yellow">
         <li><a href="javascript:;" class="link">链接1</a></li>
         <li><a href="javascript:;" class="link">链接2</a></li>
         <li><a href="javascript:;" class="link">链接3</a></li>
     </ul>
 </body>
 </html>

事件绑定

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <script>
         window.onload = function () {
             /**
              * addEventListener()
              * - 通过这个方法可以为元素节点同时绑定多个响应函数
              * @param 事件
              * @param 回调函数
              * @param 是否在在捕获阶段触发事件,需要一个boolean,一般为false
              */
             var btn = document.getElementById("btn");
             btn.addEventListener("click", function () {
                 alert("123");
            })
             btn.addEventListener("click", function () {
                 alert("456");
            })
             btn.addEventListener("click", function () {
                 alert("789");
            })
        }
     </script>
 </head>
 <body>
     <button id="btn">按钮</button>
 </body>
 </html>

事件传播

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <style>
         #box1 {
             width: 300px;
             height: 300px;
             background-color: black;
        }
 
         #box2 {
             width: 200px;
             height: 200px;
             background-color: green;
        }
 
         #box3 {
             width: 100px;
             height: 100px;
             background-color: yellow;
        }
     </style>
     <script>
         window.onload = function () {
             /**
              * 事件的传播分为三个阶段:
              * 1. 捕获阶段:在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
              * 2. 目标阶段:事件捕获到目标元素,捕获结束开始在目标元素上触发事件
              * 3. 冒泡阶段:事件从目标元素向他的父元素传递,一次触发父元素上的事件
              */
             document.getElementById("box1").addEventListener("click", function () {
                 alert("我是div1");
            });
             document.getElementById("box2").addEventListener("click", function () {
                 alert("我是div2");
            });
             document.getElementById("box3").addEventListener("click", function () {
                 alert("我是div3");
            });
        }
     </script>
 </head>
 <body>
     <div id="box1">
         <div id="box2">
             <div id="box3"></div>
         </div>
     </div>
 </body>
 </html>

拖拽

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <style>
         #box1 {
             width: 300px;
             height: 300px;
             background-color: black;
             position: absolute;
        }
 
         #box2 {
             width: 100px;
             height: 100px;
             background-color: yellow;
             position: absolute;
             left: 100px;
        }
     </style>
     <script>
         window.onload = function () {
             var box1 = document.getElementById("box1");
             // 为div绑定鼠标按下事件
             box1.onmousedown = function (event) {
                 // div的偏移量:鼠标.clientX - 元素节点.offsetLeft
                 // div的偏移量:鼠标.clientY - 元素节点.offsetTop
                 var ol = event.clientX - box1.offsetLeft;
                 var ot = event.clientY - box1.offsetTop;
                 // 为document绑定鼠标移动事件
                 document.onmousemove = function (event) {
                     box1.style.left = event.clientX - ol + "px";
                     box1.style.top = event.clientY - ot + "px";
                }
                 // 为document松开鼠标移动事件
                 document.onmouseup = function () {
                     // 当鼠标松开时,被拖拽元素固定在当前位置:取消document的onmousemove事件
                     document.onmousemove = null;
                     // 取消document的onmouseup事件,目的是将本次事件设为一次性事件,确保每次拖拽都为新事件
                     document.onmouseup = null;
                }
                 /**
                  * 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,此时会导致拖拽功能异常,这是浏览器的默认行为
                  * 如果不希望发生此行为,则可以通过return false取消
                  */
                 return false;
            }
        }
     </script>
 </head>
 <body>
     <p>文字</p>
     <div id="box1"></div>
     <div id="box2"></div>
 </body>
 </html>

鼠标滚轮

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <style>
         #box1 {
             width: 100px;
             height: 100px;
             background-color: black;
             position: absolute;
        }
     </style>
     <script>
         window.onload = function () {
             var box = document.getElementById("box1");
             document.onwheel = function (event) {
                 var y = event.deltaY;
                 var height = box.style.height;
                 height = Number(height.split("p")[0]);
                 box.style.height = height + y + "px";
            }
        }
     </script>
 </head>
 <body>
     <div id="box1"></div>
 </body>
 </html>

键盘

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <style>
         #box {
             height: 100px;
             width: 100px;
             background-color: yellow;
             position: absolute;
        }
     </style>
     <script>
         window.onload = function () {
             var box = document.getElementById("box");
             /**
              * 键盘事件一般绑定到有焦点的对象
              */
             document.onkeydown = function (ev) {
                 if (ev.keyCode == 37) {
                     box.style.left = Number(box.style.left.split("p")[0]) - 10 + "px";
                } else if (ev.keyCode == 38) {
                     box.style.top = Number(box.style.top.split("p")[0]) - 10 + "px";
                } else if (ev.keyCode == 39) {
                     box.style.left = Number(box.style.left.split("p")[0]) + 10 + "px";
                } else if (ev.keyCode == 40) {
                     box.style.top = Number(box.style.top.split("p")[0]) + 10 + "px";
                }
            }
 
        }
     </script>
 </head>
 <body>
     <div id="box"></div>
 </body>
 </html>
 

BOM

浏览器对象模型,BOM可以使我们通过JS操作浏览器

Window:代表的是整个浏览器窗口,同时window也是网页中的全局对象

Navigator:代表的是当前浏览器的信息,通过该对象可以识别不同的浏览器

Location:代表的是当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面

History:代表的是当前浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,只能操作浏览器向前或向后翻页,并且只对当次访问有效

Screen:代表用户的屏幕信息

定时器

window中有两个方法可以起到定时器的作用

 

setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。

setInterval()

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <script>
         window.onload = function () {
             var count = document.getElementById("count");
             var num = 1;
             /**
              * setInterval()方法的返回值为该计数器的ID,ID可用作clearInterval()方法的参数用来停止定时器
              */
             var id = setInterval(function () {
                 count.innerHTML = num++;
            }, 1000);
             setInterval(function () {
                 console.log(id);
            }, 1000);
             document.getElementById("btn").onclick = function () {
                 clearInterval(id);
            }
        }
     </script>
 </head>
 <body>
     <p id="count">1</p>
     <button id="btn">咋瓦鲁多</button>
 </body>
 </html>

setTimeout

 setTimeout(function () {
     alert("定时任务");
 }, 5000);

切换图片升级版

注意在开启定时器时关闭上一个定时器

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>Title</title>
     <script>
         window.onload = function () {
             var id;
             var imgArray = ["img/1.png", "img/2.png", "img/3.png", "img/4.png",];
             var length = imgArray.length;
             var index = 0;
             document.getElementById("btn1").onclick = function () {
                 // 开启此次定时任务时取消上次定时任务,防止开启多个定时器
                 clearInterval(id);
                 id = setInterval(function () {
                     index++;
                     index = index % length;
                     document.getElementById("img").src = imgArray[index];
                }, 500);
            }
             document.getElementById("btn2").onclick = function () {
                 clearInterval(id);
            }
        }
     </script>
 </head>
 <body>
     <img id="img" width="300px" height="300px" src="img/1.png"/>
     <button id="btn1">开始</button>
     <button id="btn2">停止</button>
 </body>
 </html>

JSON

 <script>
     /**
      * JSON分类:1.对象{} 2.数组[]
      *
      * JSON允许的值:1.字符串 2.数值 3.布尔值 4.null 5.对象 6.数组
      */
     var js = '{"name": "ccy", "age": "22"}';
     // 将JSON字符串转换为JS对象:JSON.parse(JSON)返回值为JS对象
     var parse = JSON.parse(js);
     console.log(parse.name);
     console.log(parse.age);
     // 将JS对象转换为JSON字符串:SON.stringify(JS对象)返回值为JSON字符串
     var obj = {name: "zfs", age: 22};
     js = JSON.stringify(obj);
     console.log(js);
 </script>
posted @ 2022-07-05 15:56  雙雙  阅读(40)  评论(0编辑  收藏  举报