JavaScript基础

目录

 

目录

JavaScript

一、初步认识JavaScript

二、JavaScript基础

1、JS编写位置

2、JS基本语法

3、基本数据类型

4、引用数据类型(Object)

5、数据类型的强制转换

6、运算符

7、代码块

8、流程控制语句

9、变量与对象保存位置

10、对象的遍历

10.对象补充

11、函数(Function)

11.2.call()、apply()方法

11.3.作用域

11.4.this(上下文对象)

11.5.构造函数

11.6.原型(prototype)

11.7.toString方法

11.8.垃圾回收(GC)

12、数组(Array)

1、数组特点

2、数组的操作

3、二维数组

4、数组的方法

slice()

splice()

join()

filter()

sort()

5、遍历数组

13、常用类和方法

13.1.包装类

13.2.Date

13.3.Math

13.4.字符串的相关的方法

13.5.正则表达式

13.6.正则表达相关方法

13.7常用正则表达式

14、DOM(Document Object Model)

14.1.DOM介绍

14.2.DOM查询

14.3.DOM其它属性和方法

14.4.DOM修改(增、删、改)

14.5.DOM对CSS的操作

读取和修改内联样式

读取元素的当前样式

其他的样式相关的属性

事件(Event)

事件

绑定事件的方式

文档的加载

事件对象(event)

事件的冒泡(Bubble)

事件的委派

事件的绑定

事件的传播

常用事件

鼠标事件

键盘事件

BOM

History

Location

window

定时器

setTimeout 延时调用

直接修改元素的类css

JSON

JSON 格式

JSON工具类

other

localStorage

sessionStorage

eval()

编码

原生js

原生js实现复制内容到剪切板



JavaScript

一、初步认识JavaScript

起源

  • JavaScript诞生于1995年,它的出现主要是用于处理网页中的前端验证。

  • 所谓的前端验证,就是指用户输入的内容是否符合一定的规则。

  • 比如:用户名的长度,密码的长度,邮箱的格式等。

实现

一个完整的JavaScript实现由以下三个部分构成:

  1. ECMAScript

  2. DOM

  3. BOM

二、JavaScript基础

  • 控制浏览器弹出一个警告框 alert()

  • 用于弹出一个带有确认和取消按钮的提示框 confirm()

    需要一个字符串作为参数,该字符串将作为提示文字显示出来

    如果用户点击确认则会返回true,点击取消则返回false(可以对一个事件是否执行,进行判断)

  • 弹出一个提示框 prompt()

  • 让计算机在页面(body)中输出一个内容 document.write()

  • 向控制台输出一个内容 console.log()

1、JS编写位置

1.1、JS代码写到script标签中

<script type="text/javascript">
    
    alert("helloWorld!");

</script>

1.2、JS代码写到外部js文件中

通过script标签引入写到外部文件中可以在不同的页面中同时使用

注意:script标签一旦用于引入外部文件,就不能再编写代码,即使编写浏览器也会忽略

<script src="./demo.js"></script>

1.3、JS代码写到标签属性中

缺点是结构与行为耦合,不方便维护,不推荐使用

<body>
    <a href="javascript:alert('让你点你就点!');">点我一下</a>
    <a href="javascript:;">你也点我一下</a>

    <button onclick="alert('讨厌,你点我干嘛');">点击</button>
</body>

2、JS基本语法

  1. JS中严格区分大小写

  2. JS中每一条语句以分号(;)结尾

    若不写分号,浏览器会自动添加,但是会消耗一些系统资源,而且有些时候,浏览器会加错分号,所以在开发中分号必须写

  3. JS中会忽略空格和换行

  4. 字面量与变量

    字面量:不可改变的值。如:1、 2、 1.0 、True

    变量:保存字面量,变量的值可以任意改变,可以对字面量进行描述

  5. 声明变量

    在js中使用var关键字来声明一个变量

  6. 标识符

    与C中基本类似,除此以外,在js命名一个标识符可以含有$。

    关键字与保留字参考:

     命名一个标识符时需要遵守如下规则:

    a、标识符中可以含有字母、数字、_、$

    b、标识符不能以数字开头

    c、标识符不能是ES中的关键字或保留字

    d、标识符一般都采用驼峰命名法

    首字母小写,除首字母外的每个单词的开头字母大写。如:helloWorld

3、基本数据类型

3.1、Number

整数、浮点数、NaN

NaN:Not a Number

NaN(Not a Number,非数)是计算机科学中数值数据类型的一类值,表示未定义或不可表示的值。常在浮点数运算中 使用。首次引入NaN的是1985年的IEEE 754浮点数标准。

<script>
		var a="abk";
		var g="cdf";
        console.log(a*b);
//NaN
</script>

JS中可以表示的数字的最大值(1.7976931348623157e+308)

<script>
    console.log(Number.MAX_VALUE);
//1.7976931348623157e+308
</script>
JS中可以表示的大于0的最小值(5e-324)
<script>
        console.log(Number.MIN_VALUE);
//5e-324
</script>

检查数据类型        typeof

<script>
        console.log(typeof Number.MAX_VALUE);
		console.log(Number.MAX_VALUE*Number.MAX_VALUE);
//number
</script>

Infinity

<script>
        console.log(Number.MAX_VALUE*Number.MAX_VALUE);
//Infinity(∞)
</script>

3.2、string

没什么好说的,就那样

<script>
	var str="我说:\"今天天气真不错!\"";
    alert(str);
</script>

3.3、boolean

主要用来逻辑判断

True:真         False:假

3.4、Null

Null这个值专门用来表示一个为空的对象

<script>
	console.log(typeof null);
//object
</script>

3.5、undefined(未定义)

当声明一个变量,但是并不给变量赋值时,它的值就是undefined。

3.7、Symbol,BigInt

  

 Symbol

        JavaScript标准中规定对象的key只能是 StringSymbol 类型,区别在于 String 类型的key可以重复而 Symbol 类型的key是唯一的Symbol 的本质是表示一个唯一标识。每次创建一个Symbol,它所代表的值都不可能重复。

const sym = Symbol('cat');

  Symbol特点

1、唯一性,即使是同一个变量生成的值也不相同

2、隐藏性,不能被遍历,访问

调用 Object.getOwnPropertySymbols(对象),可以访问到所有Symbol

BigInt用来表示任意大的整数

Number < 2的53 -1

BigInt表示方法

1、在整数后加n

123n

2、调用BigInt()构造函数

let bigInt = BigInt("999");

console.log(bigInt) //999n

注意:调用BigInt()构造函数,会对参数进行转换

true --- 1 BigInt(true) --- 1n

false --- 0 BigInt(true) --- 0n

'整数' --- 整数 BigInt('123') --- 123n

无法转换的数据类型

RangeError:浮点数

TypeError:null,undefined

SyntaxError:非整数的字符串,一般对象,函数对象,元素个数大于1的数组

 

3.8、基本类型存放位置

NAME
字符串 存在堆中,栈中为引用地址;如果存在相同字符串,则引用地址相同
String对象存在堆中,
数字 小整数存在栈中,其它存在堆中
其它类型 引擎初始化时分配唯一地址,栈中的变量存的是唯一的引用

栈和堆的区别:JavaScript 中堆和栈的区别you_wne的博客-CSDN博客js堆和栈的区别

变量存储机制:JavaScript中变量到底是存储在「栈」还是「堆」上? - 知乎 (zhihu.com)

4、引用数据类型(Object)

object(使用基本数据类型的数据,所创建的对象都是独立的,不能够成一个整体。

对象可以保存多个不同数据类型的属性)

对象的分类

  1. 内建对象

    -由ES标准中定义的对象,在任何ES的实现中都可以使用

    -比如:Math String Number Object……

  2. 宿主对象

    -由JS的运行环境提供的对象,主要指由浏览器提供的对象

    -比如:BOM DOM(console.log())

  3. 自定义对象

    -由开发人员自己创建的对象

创建对象的方式:

1、使用new关键字调用的函数,是构造函数constructor

        构造函数是专门用来创建对象的函数

        使用typeof检查一个对象时,会返回object

var obj = new Object();
<script>
        var obj=new Object();
        obj.name='张三';
        console.log(typeof obj);
        console.log(obj.name);
</script>

向对象中添加属性:

$$
语法:对象.属性名 = "属性值";
$$

obj.name="孙悟空";

注意:如果读取对象中没有的属性,不会报错而是会返回undifined

2、

使用对象字面量来创建一个对象

语法:	
	①var obj = {};
	
	②var obj = {
		属性名 :"属性值",
		属性名 :"属性值",
		属性名 :"属性值",
		属性名 :"属性值"
	}
属性名和属性值是一组一组的名值对结构

名和值之间使用':'连接,多个名值对之间使用','隔开

若一个属性之后没有其他的属性,则不需要加','
	

注意:对象字面量的属性名引号可加可不加,建议不加

对象的属性名类型都是字符串,符合命名规则的属性,可以不加引号

如果使用特殊字符、名字(非合法命名规则),则属性名必须加引号

特殊字符、名字的读取:obj["属性名"] = 属性值

var obj3 = {888name :"hello" };
var obj4 = {	    :"hello" };

//报错
此时会报错

修改对象的属性值:

$$
语法:对象.属性名=新值
$$

删除对象的属性:

$$
语法:delete 对象.属性名
$$

注意:如果使用特殊的属性名,不能采用 . 的方式来操作

而是:语法:对象["属性名"]=属性值

in 运算符:

作用:检查一个对象中是否含有指定的属性

如果有则返回true,没有则返回false

语法: "属性名" in 对象

<script>
        var obj=new Object();
        obj.name='张三';
        console.log("name" in obj);
//true
</script>

对象的比较:

当比较两个基本数据类型的值时,就是比较值

当比较两个引用数据类型时,它是比较的对象的内存地址

5、数据类型的强制转换

5.1、其他的数据类型转换为String

  • 方式一:调用toString()

    方法:x.toString()

    注意:null和undefined不能调用toString()

    <script>
            var num=123;
            var numR=num.toString();
            console.log(typeof numR);
    //string
    </script>

  • 方式二:调用String()

    <script>
            var a=12;
            var b=String(a);
            console.log(typeof b);
    //string
    </script>
     

5.2、其他的数据类型转换为Number

  1. 使用Number()函数

    string-->number

    • 如果是纯数字字符串,则直接将其转换为数字

      <script>
               var a='123';
               var b=Number(a);
               console.log(typeof b);
      //number
      </script>

    • 如果字符串中有非数字的内容,则转换为NaN

      <script>
              var c='123bbba';
              var d=Number(c);
              console.log(d);
              console.log(typeof d);
      //NaN
      //number
      </script>

    • 如果字符串是一个空串或者是一个全是空格的字符串,则转换为0

      <script>  
             var a='';
              var b=Number(a);
              console.log(b);
              console.log(typeof b);
      //0
      //number
      </script>

    Boolean-->number

    true------1, false------0

    Null-->0

    undefined-->NaN

    2、调用parseInt()、parseFloat()函数

    parseInt()、parseFloat()函数可以分别将一个字符串中的有效整数、有效浮点数解析出来,然后转换为number

    允许前导和尾随空格。       

    parseInt(" 123 ");        //123

    如果第一个字符不能转换为数字,parseInt() 返回 NaN。       

    parseInt("")       // NaN

    指定字符串中的第一个字符是否为数字。如果是,它会解析字符串直到到达数字的末尾,并将数字作为数字而不是字符串返回。只会对解析到的第一个小数点生效。

    parseInt(" 123as12");        //123

    parseFloat(".123as1");        //0.123

    parseFloat(".123.as");        //0.123

    可以在parseInt()中传递第二个参数,来指定数字的进制

    <script>
            var a='123xsdd';
            var b=parseInt(a);
            console.log(b);
            console.log(typeof b);
    //123
    //number
    </script>	

5.3、其他的数据类型转换为Boolean

1、使用Boolean()函数

  • 数字-->布尔

    除了0和NaN,其余的都是true

  • 字符串-->布尔

    除了空串,其余的都是true

  • null和undefined都会转换为false

  • 对象也会转换为true

2、对该数据类型进行两次取反操作

5.4、隐式转换

  1. 任何值和字符串相加都会转换为字符串,并做拼串操作

    <script>
    		var c=123;
    		c=c+"";
    		console.log(typeof c);
    //string	
    </script>
  2. 任何值做' - * / ' 运算时,都会自动转换为Number

  3. 在其它数据类型前使用'正号+',会将其转换为Number

6、运算符

6.1、算术运算符

当对非number类型的值进行运算时,会将这些值转换为Number(若不能转换为number,则运算会报错),然后在运算

任何值和NaN做运算都得NaN

  1. +

    对两个值进行加法运算

    对两个字符串进行拼串

  2. -

  3. *

  4. \

  5. %

6.2、一元运算符

只需要一个操作数

+ 正号(不会对数字产生任何影响)

- 负号(对数字进行取反)

6.3、逻辑运算符

! :对布尔值进行取反操作

若对非布尔值进行非运算,则会先转换为布尔值,然后再取反

&&:具有短路性

||:具有短路性

&&和||非布尔值的情况:

对非布尔值进行与或运算时,会先将其转换为布尔值,然后再运算,并且返回原值

<script>
 		var result=5 && 6;
 		console.log("result="+result);
 //result=6
 </script>

6.4、关系运算符

通过关系运算符可以比较两个值之间的大小关系,如果关系成立则会返回true,反之返回false

任何值和NaN做任何比较,返回的都是false

对于非数值进行比较时,会将其转换为数字然后再比较

<script>
		console.log(1>true);
//false
</script>

两边都是字符串时,比较的是字符串的字符编码,比较字符编码是一位一位进行比较,若两位一样,则比较下一位

<script>
		console.log("axdf">"sddc");
//false
</script>

在字符串中使用转义字符输入Unicode编码(\u四位编码)

<script>
		console.log("\u0031");
//1
</script>
 

6.5、相等运算符

  1. ==

    相等运算符,比较两个值是否相等,相等返回true,否则返回false

    当两边值的类型不同时,则会自动转换为相同的类型

  2. !=

  3. ===

    值相等,类型一致,否则返回false

  4. !==

    两边的值的类型不同,直接返回true

注意:undefined衍生自null,所以两个值做相等判断时,会返回true

NaN不和任何值相等,包括它本身,可以通过isNaN()函数来判断一个值是否是NaN,若是则true,否则false

isNaN()                        :isNaN函数,会先将测试子,进行Number转换,然后对其进行测试

Number.isNaN()           :不会将值转换为数字,并且不会为任何非数字类型(NaN)的值返回 true。

6.6、条件运算符

条件运算符又叫三元运算符

语法:

条件表达式?语句1:语句2;

6.7、运算符的优先级

. [ ] NEW
()
++、--
!、~、+(单目)、-(单目)、typeof、void、delete
%、*、/
+(双目)、-(双目)
<<、>>、>>>
<、<=、>、>=
==、!=、===
&
^
|
&&
||
?:
=、+=、-=、/=、%=、<<=、>>=、>>>=、&=、^=、|=
,

7、代码块

在JS中可以使用{}来为语句进行分组,同一个{}中的语句称为一组语句,它们要么都执行,要么都不执行

在代码块{}的后边不需要加";"

代码块只具有分组的作用,没有其它的用途。代码块中的内容,在外部是完全可见的

8、流程控制语句

if、switch、while、for(--for(;;)<==>while(1)程序进入死循环--)

prompt()可以弹出一个提示框,该提示框中会带有一个文本框

用户可以在文本框中输入一段内容,该函数需要一个字符串作为参数,作为提示框的提示文字

输入的内容将会作为函数的返回值,可以定义一个变量来接收该内容

prompt()函数的返回值是String类型的,

+prompt()-->number类型

var score=prompt("请输入小明的期末成绩:");

9、变量与对象保存位置

栈内存

变量
x111
object0x9876

保存在栈内存中:
	JS中的变量、基本数据类型的值
	
	值与值之间是独立存在,修改一个变量不会影响其它的变量

保存在堆内存中:
	对象、函数、数组
	
	每创建一个新的对象,就会在堆内存中开辟出一个新的空间,

	变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象的引用,当一个通过变量修改属性时,另一个也会受影响

10、对象的遍历

使用in检查对象中是否含有指定属性

语法:"属性名" in 对象

如果在对象中含有该属性,则返回true 如果没有则返回false

循环遍历对象自身的和继承的可枚举属性(不含Symbol属性).  
<script>

var obj = {'0':'a','1':'b','2':'c'};  
//遍历对象中的属性  
for(var i in obj) {  
     console.log(i,":",obj[i]);  
}  


 var obj = {
    name:"小王",
    age:20,
    gender:"男",
    Sayname:()=>{
       console.log(obj.name)
    }
  };
     for(var i in obj){
     console.log(obj);//遍历对象,次数为属性的个数
     console.log(`属性名=${i}`);  //遍历属性
     console.log(`属性值=${obj[i]}`);//遍历属性值
}
</script>

枚举对象中的属性 for...in 语法:

for(var 属性名 in 对象){  
  
}  

for...in语句的循环体会执行多次,对象中有几个属性就会执行几次, 每次讲一个属性名赋值给我们定义的变量,我们可以通过它来获取对象中的属性


10.对象补充

使用对象字面量,在创建对象时直接向对象中添加属性 语法:

var obj = {  
    属性名:属性值,  
    属性名:属性值,  
    属性名:属性值,  
    属性名:属性值  
} 

基本数据类型和引用数据类型

基本数据类型
StringNumberBooleanNullUndefined

引用数据类型         Object

基本数据类型的数据,变量是直接保存的它的值。
变量与变量之间是互相独立的,修改一个变量不会影响其他的变量。
引用数据类型的数据,变量是保存的对象的引用(内存地址)。
如果多个变量指向的是同一个对象,此时修改一个变量的属性,会影响其他的变量。
比较两个变量时,对于基本数据类型,比较的就是值,
对于引用数据类型比较的是地址,地址相同才相同

11、函数(Function)

函数也是一个对象

函数中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码

使用typeof检查一个函数时会返回function

创建函数

创建一个函数对象:

	var fun = new Function();
	
注意:封装到函数中的代码不会立即执行,到调用的时候才会执行	

 //创建函数对象
var fun = new Function("console.log('hello javascript!')"); 
	fun();

函数声明

function 函数名([形参1,形参2...形参N]){  
语句...  
}  

函数表达式

var 函数名 = function([形参1,形参2...形参N]){  
语句...  
};  

调用函数

语法:函数对象([实参1,实参2...实参N]);
如:fun() 
    sum() 
	alert()
	Number() 
	parseInt()
**********************************************************************************
function sayName(){
        *****
};
sayName();-->调用函数  *相当于使用的函数的返回值
sayName;-->函数对象	   *相当于使用的函数对象
当我们调用函数时,函数中封装的代码会按照编写的顺序执行
调用函数时,解析器不会检查实参的数量、类型,所以要注意是否有可能接收到非法的参数,如果有可能则需要对参数进行类型的检查
函数的实参可以是任意数据类型(sum(123,"hello");)


立即执行函数

函数定义完,立即被调用,这种函数叫做立即执行函数

立即执行函数往往只会执行一次

(function(a,b){  								
    console.log("a = "+a);  						
    console.log("b = "+b);  						
})(123,456);									


((a,b)=>{
    console.log("a = "+a);  
    console.log("b = "+b); 
})(123,456); 
语法:
((形参1,形参2...形参n)=>{
  *********  
})(实参1,实参2..实参n);

遍历对象

for(var v in obj){
    document.write("property:name ="+v+"value="+obj[v]+"<br/>" );  
}  

形参和实参
形参:形式参数
定义函数时,可以在()中定义一个或多个形参,形参之间使用,隔开
定义形参就相当于在函数内声明了对应的变量但是并不赋值,
形参会在调用时才赋值。
实参:实际参数
调用函数时,可以在()传递实参,传递的实参会赋值给对应的形参,
调用函数时JS解析器不会检查实参的类型和个数,可以传递任意数据类型的值。
如果实参的数量大于形参,多余实参将不会赋值
如果实参的数量小于形参,则没有对应实参的形参将会赋值undefined

返回值(RETURN),就是函数执行的结果
语法:return 值
可以通过一个变量来接收返回值
return后边的代码都不会执行,一旦执行到return语句时,**函数将会立刻退出
return后可以跟任意类型的值,可以是基本数据类型,也可以是一个对象
如果return后不跟值,或者是不写return则函数默认返回undefined
js中Return的用法 (cncsto.com)

JAVASCRIPT在事件中调用函数时用return返回值实际上是对window.event.returnvalue进行设置

而该值决定了当前操作是否继续。

当返回的是true时,将继续操作。

当返回是false时,将中断操作。

<script>
var sum = (a,b,c)=>{					 
    var d = a+b+c;							 
    return d;							 
 }												  
    var result = sum(1,2,3);				
    console.log("result = ",result);				        
 
function sum2(a,b,c){
     var d = a+b+c;
//   return "hello";
     return undefined;
}

    console.log(sum2(1,2,3));   
</script>
  

break、continue和return:

break
退出循环

continue
跳过当次循环

return	
退出函数,不会执行代码块中return 以后的语句
return false,事件处理函数会取消事件,不再继续向下执行(阻止执行的默认行为)。比如表单将终止提交
return True, 就相当于执行符,执行终止默认的事件行为

参数,函数的实参也可以是任意的数据类型。

**方法(method)**
可以将一个函数设置为一个对象的属性,
当一个对象的属性是一个函数时,我们称这个函数是该对象的方法。
**调用这个函数就说调用这个对象的方法(method)**

调用方式:对象.方法名();
函数名()

<script>
    var obj = {
            name:"小王",
            age:20,
            gender:"男",
            Sayname:func(){
                console.log("今天天气真不错!")
            }
        };
    obj.Sayname();--调方法     |   fun(); --调方法
    console.log(obj.Sayname);//输出整个函数
   
</script>


11.2.call()、apply()方法

CALL()与APPLY()
1、作用:改变this的指向
这两个方法都是函数对象的方法需要通过函数对象来调用
通过两个方法可以直接调用函数,并且可以通过第一个实参来指定函数中this
不同的是call是直接传递函数的实参而apply需要将实参封装到一个数组中传递
var person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}
var person1 = {
  firstName:"Bill",
  lastName: "Gates"
}
console(person.fullName.call(person1, "Seattle", "USA"));

console(person.fullName.apply(person1, ["Seattle", "USA"]));
//若不将实参封装到数组中会显示:
//Uncaught TypeError: CreateListFromArrayLike called on non-object

arguments

在调用函数时,浏览器每次都会传递进两个隐含的参数:
1,this 2,封装实参的对象arguments
arguments是一个类数组对象,它可以通过索引来操作数据
在调用函数时,所传递的实参都会在arguments中保存
arguments.length可以用来获取实参的长度
即使不定义形参,也可以通过arguments来使用实参
arguments中有一个属性callee表示当前执行的函数对象
function test() {
        var s = "";
        for (var i = 0; i < arguments.length; i++) {
            alert(arguments[i]);
            s += arguments[i] + ",";
        }
        return s;
}
test("name", "age");
输出结果:
name,age


11.3.作用域

作用域简单来说就是一个变量的作用范围。 在JS中作用域分成两种:

1.全局作用域

直接在SCRIPT标签中编写的代码都运行在全局作用域中
全局作用域在打开页面时创建,在页面关闭时销毁
全局作用域中有一个全局对象window,window对象由浏览器提供,它代表的是整个的浏览器的窗口,可以在页面中直接使用
在全局作用域中创建的变量都会作为window对象的属性保存
在全局作用域中创建的函数都会作为window对象的方法保存
在全局作用域中创建的变量和函数可以在页面的任意位置访问
在函数作用域中也可以访问到全局作用域的变量
尽量不要在全局中创建变量

2.函数作用域

函数作用域是函数执行时创建的作用域,每次调用函数都会创建一个新的函数作用域
函数作用域在函数执行时创建,在函数执行结束时销毁
调用开辟内存,函数执行结束,释放内存
在函数作用域中能使用全局作用域中的变量;在全局作用域中无法使用函数作用域中的变量
当在函数作用域中使用一个变量时,它会先在自身作用域中寻找 如果找到了则直接使用,如果没有找到则到上一级作用域中寻找 如果找到了则使用,找不到则继续向上找,直到找到全局作用域 如果全局作用域依然没有找到,则会报错ReferenceError
在函数中用var声明的变量,是局部变量;在函数外用var声明的变量是全局变量
<script>
    var a = 10;
	function fun(){
        var a = 20;
        var b = 30;
        console.log(a);
    }
	fun();//20
</script>

3.变量的声明提前

在全局作用域中,使用VAR关键字声明的变量会在所有的代码执行之前被声明,但是不会赋值
注;在执行前,浏览器会扫描var关键字,若有则使变量地位提升至最开头
所以我们可以在变量声明前使用变量。但是不使用var关键字声明的变量不会被声明提前
在函数作用域中,也具有该特性,使用var关键字声明的变量会在函数所有的代码执行前被声明
如果没有使用var关键字声明变量,则变量会变成全局变量(函数作用域中)
<script>
//变量的声明提前
  console.log("a="+a);
  var a = 123;//输出undefined

function fun(){
  console.log(b);
   var b = 10;
}
   fun();//输出undefined

*在函数中,不使用var声明的变量会成为全局变量*
    function fun(){
    d = 10;//window.d
}

 </script>

4.函数的声明提前

在全局作用域中,使用函数声明创建的函数(FUNCTION FUN(){}),会在所有的代码执行之前被创建
我们可以在函数声明前去调用函数,但是使用函数表达式(var fun = function(){})创建的函数没有该特性
函数作用域中,使用函数声明创建的函数,会在所有的函数中的代码执行之前就被创建好了
<script>
//函数的声明提前
    console.log(fun2(14,54));//成功,函数声明,会被提前创建  //68
     function fun2(a,b){//定义形参,相当于在函数作用域声明了变量
         return a+b;
   };

    console.log(fun3(45,54));//失败,函数表达式,不会被提前创建
     var fun3 = (a,b)=>{
        return a+b;
};
</script>
<script>
//练习
   var a = 123;
   function fun(a){
        alert(a);
        a = 456;//这里不是隐式声明,而是对传入的形参的赋值
        alert(a);//456
        }
   fun(123);//123
   alert(a);//123

作用域更多详情请参考下面网址:https://www.php.cn/js-tutorial-473339.html


11.4.this(上下文对象)

1、this来自哪儿

我们每次调用函数时,解析器都会将一个上下文对象作为隐含的参数传递进函数。 使用this来引用上下文对象,根据函数的调用形式不同,this的值也不同。

指向当前对象

3、为什么要使用this

使用this可以及其灵活的调用,返回不同的结果,使代码结构清晰

function person(){
  return this.name.toUpperCase()
}
function speak(){
  var regards = 'hello ' + person.call(this)
  console.log(regards)
}
var me = {
  name:"lilei"
}
var you = {
  name:"hanmeimei"
}
person.call(me)  //LILEI  call的第一个参数可以改变this指向
person.call(you)//  HANMEIMEI
speak.call(me) //hello LILEI
speak.call(you) //hello HANMEIMEI

2、this的使用环境

THIS的不同的情况:
this(调用函数的那个对象) this是函数的上下文对象,根据函数的调用方式不同会指向不同的对象
1.以函数的形式调用时,this是window
2.以方法的形式调用时,this是调用方法的对象
3.以构造函数的形式调用时,this是新建的那个对象
4.使用call和apply调用时,this是指定的那个对象(箭头函数无效)
5.在全局作用域中this代表window
// 使用工厂方法创建对象,可以大批量创建对象
 function sayName(name,age,gender){
     var obj = {
         name,
         age,
         gender,
         sayHi:()=>{
            console.log(`我是${obj.name},我今年${obj.age}岁了,我是一个${obj.gender}生`);
     }
  }
     return obj;
 }
var obj2 = sayName("李四",20,"男");
var obj3 = sayName("张三",19,"男");
obj2.sayHi();
obj3.sayHi();

//使用工厂方法创建的对象,使用的构造函数都是Object
//导致无法区分出多种不同类型的对象
更多详情请参考以下网址
彻底搞懂JavaScript中的this指向问题 - 知乎 (zhihu.com)

11.5.构造函数

1、为什么要使用构造函数?

var p1 = { name: 'zs', age: 6, gender: '男', hobby: 'basketball' };
var p2 = { name: 'ls', age: 6, gender: '女', hobby: 'dancing' };
var p3 = { name: 'ww', age: 6, gender: '女', hobby: 'singing' };
var p4 = { name: 'zl', age: 6, gender: '男', hobby: 'football' };

避免一直使用重复性的代码,使用构造函数后只需要传入参数,极大的减少了程序员的工作量

在创建构造函数后,

(1) 当以 new 关键字调用时,会创建一个新的内存空间,标记为XX 的实例。

(2)函数体内部的 this 指向该内存

例子:

<script>

function Person(name , age , gender){  
    this.name = name;  
    this.age = age;  
    this.gender = gender;  
    this.sayName = function(){  
        console.log(this.name);  
    };  
} 
//创建一个对象的实例
var per = new Person("孙悟空",18,"男");
per.sayName();
</script>

2、构造函数的特点

构造函数是专门用来创建对象的函数
一个构造函数我们也可以称为一个
通过一个构造函数创建的对象,我们称该对象是这个构造函数的实例
通过同一个构造函数创建的对象,我们称为一类对象
构造函数就是一个普通的函数,只是他的调用方式不同
如果直接调用,它就是一个普通函数
如果使用new来调用,则它就是一个构造函数

3、构造函数的执行流程

构造函数的执行流程:
1.创建一个新的对象
2.将新的对象作为函数的上下文对象(this)
3.执行函数中的代码
4.将新建的对象返回

4、instanceof用法

INSTANCEOF 用来检查一个对象是否是一个类的实例
语法:对象 instanceof 构造函数
如果该对象是构造函数的实例,则返回true,否则返回false
var per2;
var per = new Person("xiaoming");       
 console.log(per2 instanceof Person);//false

Object是所有对象的祖先,所以任何对象和Object做instanceof都会返回true


11.6.原型(prototype)

1、什么是原型,原型是如何产生的

创建一个函数以后,解析器都会默认在函数中添加一个属性PROTOTYPE
prototype属性指向的是一个对象,这个对象我们称为原型对象。 当函数作为构造函数使用,它所创建的对象中都会有一个隐含的属性执行该原型对象,可以通过___proto___来访问

 function Fun(){
 
};
var fun1 = new Fun();
var fun2 = new Fun();
console.log(Fun.prototype == fun1.__proto__);
 

2、为什么要使用原型

当在构造函数中添加方法时,每创建一个对象,都新增加一个方法,造成内存和性能的浪费(实例的方法具有唯一性)

因此,需要把重复的方法提取出来,放在一个公有的地方

注:若将方法放在全局作用域,会污染全局作用域的命名空间,使代码缺少封装性)

function Fun(){
    this.sayName = function(){
        console.log("今天天气真好啊!");
     };
  }
  var fun1 = new Fun();
  var fun2 = new Fun();
  
  fun1.sayName();
  fun2.sayName();

  console.log(fun1.sayName === fun2.sayName);//false
//说明每个对象具有不同的方法
  

3、原型对象的特点

原型对象就相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象
原型也是对象,所以它也有原型 当我们去访问对象的一个属性或调用对象的一个方法时,它会先在自身中寻找,如果在自身中找到了,则直接使用。 如果没有找到,则去原型对象中寻找,如果找到了则使用,如果没有找到,则去原型的原型中寻找,依此类推。直到找到Object的原型为止,Object的原型的原型为null, console.log(fun2.__proto__.__proto__.__proto__);//NULL 如果依然没有找到则返回undefined

hasOwnProperty() 这个方法可以用来检查对象自身中是否含有某个属性

语法:对象.hasOwnProperty("属性名")

Fun.hasOwnProperty("name");
使用in检查对象中是否含有某个属性时,若对象中没有,但原型中有,也会返回true

4、如何使用原型对象

我们可以将对象中共有的属性和方法统一添加到原型对象中, 这样我们只需要添加一次,就可以使所有的对象都可以使用

Fun.prototype.sayName = function(){
      console.log("今天天气真好啊!");
}

向原型对象中添加属性

Fun.prototype.name = "我是原型中的名字";
更多详情,请阅读以下网址(讲的清楚详细)
(68条消息) JavaScript中原型对象的彻底理解做人要厚道2013的博客-CSDN博客原型对象
帮你彻底搞懂JS中的prototype、proto与constructor(图解)码飞CC的博客-CSDN博客_doc.configuration.prototypeid js


11.7.toString方法

当我们直接在页面中打印一个对象时,实际上是输出的对象

如果我们希望输出对象的toString()返回值,可以为对象添加一个toString()方法

function Person(name,age,gender){
	this.name = name;
	this.age = age;
	this.gender = gender;
}
//修改Person原型的toString 
Person.prototype.toString = function(){  
	return `Person[name=${this.name},age=${this.age},gender=${this.gender}]`;  
};  

var per = new Person("孙悟空",18,"男");
var per2 = new Person("猪八戒",19,"男");

console.log(per.toString());
console.log(per2);

11.8.垃圾回收(GC)

1、为什么会产生垃圾?
当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,此时这种对象就是一个垃圾
2、垃圾带来的危害
占用大量的内存空间,导致程序运行变慢
3、如何解决垃圾
垃圾回收的机制
在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作
我们需要做的只是要将不再使用的对象设置null即可


12、数组(Array)

1、数组特点

数组是一个对象
存储效率比普通对象要高
数组中保存的内容我们称为元素
数组使用索引(index)来操作元素
索引指由0开始的整数
如果读取不存在的索引,会返回undefined
数组中的元素可以是任意的数据类型(基本数据类型、对象、函数、数组)
var arr = [{name:"小美",age:18}]

2、数组的操作

a、创建数组

//1、创建数组对象

var arr = new Array(); 
    arr[索引] = 值;
    arr[索引] = 值;
	arr[索引] = 值;
//使用构造函数创建数组时,也可以同时添加元素(元素作为参数传递)

var arr = new Array(10,"hello",null);
console.log(arr);//arr[10,"hello",null];

var arr = new Array(10);//表示创建了一个长度为10的数组
//2、使用字面量创建数组

var arr = [];  

b、向数组中添加元素

$$
语法;数组对象[索引] = 值;
$$

arr[0] = 123;

arr[1] = "hello";

c、创建数组时直接添加元素

$$
语法: var\ arr = [元素1,元素2....元素N];
$$

例子:

var arr = [123,"hello",true,null];  

d、获取和修改数组的长度(length)

获取长度数组.length
length获取到的是数组的最大索引+1
对于连续的数组,length获取到的就是数组中元素的个数
修改数组的长度:
数组.length = 新长度
如果修改后的length大于原长度,则多出的部分会空出来
如果修改后的length小于原长度,则原数组中多出的元素会被删除
向数组的最后添加元素:
数组[数组.length] = 值;

3、二维数组

//数组中存放数组
var arr = [[1,2,3],[4,5,6],[7,8,9]];

4、数组的方法

FUNCTIONNAMEFUNCTIONUSAGE
push()用来向数组的末尾添加一个或多个元素,并返回数组新的长度数组.push(元素1,元素2,元素N);
var arr = ["孙悟空","猪八戒","沙和尚"]; arr.push("唐僧","白龙马"); console.log(arr.length);//5
pop()用来删除数组的最后一个元素,并返回被删除的元素语法:数组.pop();
var result = arr.pop(); console.log(result);
unshift()向数组的开头添加一个或多个元素,并返回数组的新的长度数组.unshift(元素1...元素n);
arr.unshift("白龙马","唐僧");
shift()删除数组的开头的一个元素,并返回被删除的元素数组.shift();
arr.shift();
reverse()可以用来反转一个数组,它会对原数组产生影响数组.reverse();
concat()可以连接两个或多个数组,它不会影响原数组,而是新数组作为返回值返回
语法:数组1.concat(数组2,数组3...);
console.log(arr.concat(arr2,arr3,"牛魔王"));

slice()

1、作用: 可以从已有的数组中返回选定的元素

2、语法: arrayObject.slice(start,end)

3、参数: start 必须。 规定从何处开始选取。 若是负数,则从数组尾部开始选取
	  end   可选。 规定从何处结束选取。 可以是负数,不选则则一直截取到最后
		 
4、返回值:返回一个新的数组,从start到end(不包括该元素)
   
5、参数可以传递一个负值,如果是负值,则从后往前数
		 -1:倒数第一个
         
 eg:  
  
var arr = [1,2,3,4,5,6,7,0];

      var result = arr.slice(3,5);
      console.log(result);//[4,5]
      console.log(arr.slice(4));//[5,6,7,0]
      console.log(arr.slice(4,-1));//[5,6,7]
      console.log(arr.slice(4,-3));//[5]

splice()

作用:可以用来删除数组中指定元素,并使用新的元素替换  
	 该方法会将删除的元素封装到新数组中作为返回值返回
     使用splice()会影响到原数组
参数:  
	1.必须,删除的开始位置的索引  
	2.可选,删除的数量  
	3.可选,三个以后,都是替换的元素,这些元素将会插入到开始位置索引的前边  
	
var arr = [1,2,3,4,5,6,7,0];
 var result2 = arr.splice(3,2,123);
   console.log(arr);//[1,2,3,123,6,7,0]
   console.log(result2);//[4,5]
	

join()

作用:可以将一个数组转换为一个字符串
参数:
需要一个字符串作为参数,这个字符串将会作为连接符来连接数组中的元素,如果不指定连接符则默认使用
	如:join("*"),join("^")
该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回

var arr = ["孙悟空","猪八戒","沙悟净","唐僧"];

    var result = arr.join("-");

    console.log(typeof result);
	//string
	console.log(result);
	//孙悟空-猪八戒-沙悟净-唐僧
    console.log(arr);
	//["孙悟空","猪八戒","沙悟净","唐僧"]

filter()

作用:用于把Array的某些元素过滤掉,然后返回剩下的元素

参数:
需要一个回调函数,回调函数可以接收3个参数
	1、element:表示Array的某个元素
	2、index:元素的位置
	3、self:数组本身

var arr = ['A', 'B', 'C'];
var r = arr.filter(function (element, index, self) {
    console.log(element); // 依次打印'A', 'B', 'C'
    console.log(index); // 依次打印0, 1, 2
    console.log(self); // self就是变量arr
    return true;
});
	

利用filter,可以巧妙地去除Array的重复元素:

var arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
 r = arr.filter(function (element, index, self) {
    return self.indexOf(element) === index;
 });
 console.log(r.toString());
//apple,strawberry,banana,pear,orange

indexOf(element,startLocation);返回某个指定的字符串值在字符串中首次出现的位置,如果没找到则返回-1。

sort()

1、作用:
可以对一个数组中的内容进行排序,默认是按照Unicode编码进行排序
2、是否影响原数组:
影响,调用以后,会直接修改原数组
3、可以指定排序的规则,方法:
需要一个回调函数作为参数,回调函数中需要定义两个形参
浏览器将会分别使用数组中的元素作为实参去调用回调函数
4、即使对于纯数字的数组,使用sort()排序时,也会按照Unicode编码来排序,因此对数字进行排序时,可能会得到错误的结果
5、使用哪个元素调用不确定,但是肯定的是在数组中,a一定在b前边
浏览器会根据回调函数的返回值来决定元素的顺序,
     如果返回一个大于0的值,则元素会交换位置
     如果返回一个小于0的值,则元素位置不变
     如果返回一个0,则认为两个元素相等,也不交换位置

     如果需要升序排列,则返回 a-b
     如果需要降序排列,则返回b-a


function compare(a,b){  
	//升序排列  
	//return a-b;  
	  
	//降序排列  
	return b-a;  
}  

let values = [0,5,1,2,10];

values.sort(compare);

alert(values);

会影响原数组的方法:
push(),pop()
unshift(),shift()
reverse()
splice()
sort()

5、遍历数组

遍历数组就是将数组中元素都获取到 一般情况我们都是使用for循环来遍历数组

for(var i=0 ; i<数组.length ; i++){  
    //数组[i];  
}  

使用forEach()方法来遍历数组(不兼容IE8)

数组.forEach(function(value , index , obj){  
    
});  

var arr = [1,2,3"hello","nice","day"];
     arr.forEach(function(value,index,obj){
     	console.log(value);
});

FOREACH()方法需要一个回调函数作为参数
回调函数(callback):传递给另一个函数作为参数的函数(使用回调函数进行异步编程)
数组中有几个元素,回调函数就会被调用几次
每次调用时,都会将遍历到的信息以实参的形式传递进来,可以定义形参来获取这些信息
value:正在遍历的元素
index:正在遍历元素的索引
obj:被遍历对象

13、常用类和方法

13.1.包装类

在JS中为我们提供了三个包装类: String()Boolean() Number() 通过这三个包装类可以创建基本数据类型的对象 例子:

var num = new Number(2);  
var str = new String("hello");  
var bool = new Boolean(true); 

但是在实际应用中千万不要这么干。三个包装类的是给后台使用的,比如浏览器,当我们调用比如字符串的方法时,后台会临时通过包装类来创建对象,然后通过对象调用方法,完成之后就会立即销毁

当我们去操作一个基本数据类型的属性方法时,

解析器会临时将其转换为对应的包装类,然后再去操作属性和方法,

操作完成以后再将这个临时对象进行销毁。

var str = 'sunwukong'  // string 基本类型

 var s2 = str.charAt(0)

 console.log(s2)  // s

 console.log(str)  // sunwukong
 实际上在执行 var s2 = str.charAt(0) 这行代码时,后台做了很多工作:
  
  代码说明如下:

  var _str = new String('sunwukong')  
// 1.找到对应的包装类,然后通过包装类临时创建一个和基本类型值相同的对象

  var s2 = _str.charAt(0)  
// 2.然后这个对象就可以调用包装对象下的方法,并且返回给 s2

  _str = null  
// 3.最后自动销毁这个临时创建的对象

13.2.Date


日期的对象,在JS中通过Date对象来表示一个时间

创建一个Date对象: 创建一个当前的时间对象

var d = new Date(); 
 
 console.log(d);
 //输出的的是当前执行代码的时间
//Sat Mar 26 2022 20:23:14 GMT+0800 (中国标准时间)
 
创建一个指定的时间对象

**需要在构造函数中传递一个表示时间的字符串作为参数**

**日期格式:月/日/年 时:分:秒**
var d = new Date("月/日/年 时:分:秒");  


var d1 = new Date("03/26/2022 20:33:10");
    console.log(d1);

方法:

NAME
getDate()当前日期对象是几日(1-31)
getDay()返回当前日期对象时周几(0-6) 0 :周日, 1 :周一 ...
getMonth()返回当前日期对象的月份(0-11) 0 :一月, 1 :二月 ...
getFullYear()从 Date 对象以四位数字返回年份。
getHours()返回 Date 对象的小时 (0 ~ 23)。-1:前一天的最后一个小时 24:第二天的第一个小时
getMinutes()返回 Date 对象的分钟 (0 ~ 59)。-1:前一小时第一分钟 60:下一小时的第一分钟
getSeconds()返回 Date 对象的秒数 (0 ~ 59)。
getMilliseconds()返回 Date 对象的毫秒(0 ~ 999)。
getTime()返回创建当前日期对象时的时间戳 |时间戳,指的是从1970年月1日 0时0分0秒,到现在时间的毫秒数 计算机底层保存时间都是以时间戳的形式保存的。
Date.now()可以获取当前代码执行时的时间戳(var d = Date.now();测试代码的执行时间)
setHours()设置 Date 对象中的小时 (0 ~ 23),语法:Date.setHours(hour,min,sec,millisec);返回值是一个时间戳

getTime()与Date.now()

 console.time('time');
 for (var i = 0; i < 10000; i++) {
    let a = new Date().getTime();
 }
  console.timeEnd('time');
//time: 2.47998046875 ms

  console.time('date');
  for (var i = 0; i < 10000; i++) {
    let b = Date.now();  
 }
  console.timeEnd('date');
//date: 1.5029296875 ms

//1、getTime是原型上的方法Date.prototype.getTime(),而now是Date对象本身的方法Date.now()


var d = new Date();
d.getTime()       //获取的是创建d时的毫秒数,不会随时间的增加而增加


13.3.Math


Math属于一个工具类,它不需要我们创建对象,它里边封装了属性运算相关的常量和方法,我们可以直接使用它来进行数学运算相关的操作

方法

NAME
Math.PI 常量,圆周率
Math.abs() 绝对值运算
Math.ceil() 向上取整
Math.floor() 向下取整
Math.round() 四舍五入取整
Math.random() Math.random():生成一个0-1([0,1))之间的随机数
生成一个x-y之间的随机整数:Math.round(Math.random()*(y-x)+x);
Math.pow(x,y) 求x的y次幂
Math.sqrt() 对一个数进行开方
Math.max() 求多个数中最大值
Math.min() 求多个数中的最小值

注:Math.abs()、Math.ceil()、Math.floor()、Math.round()...将会返回一个新的值,不会影响原变量


13.4.字符串的相关的方法


字符串是一种类数组

使用ES6中的字符串新方法:

String.padStart(maxLength, fillString='')
//在String前面填充

or

String.padEnd(maxLength, fillString='')
//在String后面填充
来填充字符串;

const str1 = '5';

console.log(str1.padStart(2, '0'));
// expected output: "05"

const fullNumber = '2034399002125581';
const last4Digits = fullNumber.slice(-4);
const maskedNumber = last4Digits.padStart(fullNumber.length, '*');

console.log(maskedNumber);
// expected output: "************5581"

方法
length获取字符串的长度str.length;
charAt()根据索引获取指定的字符str.charAt(0-str.length-1)
charCodeAt()根据索引获取指定的字符编码str.charCodeAt(0-str.length-1)
String.fromCharCode()根据字符编码获取字符String.fromCharCode(0x1234)
concat()连接字符串str.concat(str2...)
indexOf()给定一个参数:要搜索的子字符串,搜索整个调用字符串,并返回指定子字符串第一次出现的索引。str.indexOf("h",5)
lastIndexOf()从后往前检索一个字符串中指定内容,并返回第一次出现的索引str.lastIndexOf("h")
indexOf(),lastIndexOf()需要一个字符串作为参数,这个字符串就是要检索的内容, 如果找到该内容,则会返回其第一次出现的索引,如果没有找到则返回-1    参数1:子串        参数2:开始查找的位置
slice()

可以从一个字符串中截取指定的内容,并将截取到内容返回,不会影响原变量

参数1:截取开始的位置(包括开始) 参数2:截取结束的位置(不包括结束) str.slice(参数1,参数2)
可以省略第二个参数,如果省略则一直截取到最后 str.slice(参数1...)
可以传负数,如果是负数则从后往前数
substr() substr() 和slice()基本一致,但它第二个参数不是索引,而是截取的数量str.substr(位置,数量)
substring() substring() 和slice()基本一致,但不能接受负值作为参数,如果设置一个负值,则会自动修正为0substring()中如果第二个参数小于第一个,自动调整位置
toLowerCase()将字符串转换为小写并返回str.toLowerCase()
toUpperCase()将字符串转换为大写并返回"hello world".toUpperCase()

13.5.正则表达式


1、什么是正则表达式

正则表达式用来定义一些字符串的规则

计算机可以根据这些规则来判断一个字符串是否符合规则

//将一个字符串中符合规则的内容提取出来//

类型:Object

2、创建正则表达式

$$

var reg = new RegExp("正则表达式","匹配模式")

$$

注意:使用构造函数时,由于它的参数是一个字符串,而 \ 是字符串中转义字符,如果要使用\则需要使用\\来代替`

var reg = new RegExp('a'); console.log(reg.test('asdfree'));//true

参数1,  正则表达式

参数2,匹配模式

i:忽略大小写(ignore)

g:全局匹配模式(默认为1次)(global)

在全局匹配模式下,正则表达式会对指定要查找的字符串执行多次匹配

设置匹配模式时,可以都不设置,也可以设置1个,也可以全设置,设置时没有顺序要求

3、使用字面量来创建正则表达式

语法:
var 变量 = /正则表达式/匹配模式;
(匹配模式可以多个一起写:/gi)

eg:
var reg = /a/i;

4、正则语法:

正则语法😊😊😊
|a|b == [ab]
[ ]
[^ ] 除了[^0-9]([12]false  [12a]true)
[x-y]x的ascii到y的ascii码之间的值
[a-z]小写字母[e-i]
[A-Z]大写字母
[A-z]任意字母
[0-9]任意数字
元符号
\.. 表示任意字符表示 .
\\\作为转义字符表示 \
\w任意字母、数字、下划线等价于[A-z0-9_]
\W除了字母、数字、下划线除了[ ^A-z0-9_]
\d任意的数字等价于 [0-9]
\D除了数字<=> [ ^0-9]
\s空格
\S除了空格
\b单词边界
\B除了单词边界
量词
通过量词可以设置一个内容出现的次数
量词只对它前边的一个内容起作用
{n}正好出现n次a{n}
{m,n}出现m-n次a{m,n}
{m,}m次以上a{m,}
n+匹配至少一个n的字符串相当于{1,}
n*匹配0个或多个n的字符串相当于{0,}
n?

只匹配*前面一个

匹配0个或1个n的字符串

相当于{0,1}
边界表达式
^正则开始reg = /^a/
$正则结束reg = /b$/
注意结束前一个才是结束匹配
如果在正则表达式中同时使用^ $字符串完全符合正则表达式

去掉两端的空格

var s = " f afa "; 
s = s.replace(/^\s*|\s*$/g,""); 

.*与.*?
.*:贪婪模式
.*?:非贪婪模式
*?:重复任意次,但尽可能少重复
后面加?,表示减少次数

(?=pattern) :表示获取pattern匹配值

()表示将(和)之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正在表达式中最多可以保存9个),它们可以用\1和\9的符号来引用

13.6.正则表达相关方法


test()

作用:
检查一个字符串是否符合正则表达式
如果符合返回true,否则返回false

语法:
new RegExp('字符串1').test('字符串2')
eg:
new RegExp('a').test("abc");//true

split()

作用:
可以根据指定内容将一个字符串拆分为一个数组
#正则分割字符串

参数:
需要一个字符串作为参数,将会根据字符串去拆分数组
可以接收一个正则表达式,此时会根据正则表达式去拆分数组
eg:
('23345d7rtf7eg74gue38').split(/[A-z]/);
//['23345','7','','','7','','74','','','38']

match()

作用:
可以根据正则表达式,从一个字符串中将符合条件的内容提取出来
默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索
#我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容

可以为一个正则表达式设置多个匹配模式,且顺序无所谓

match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果

eg:
 
var str = '1a2b3c4e5d6f7g';

 result = str.match(/[0-9]/g);

 console.log(result);
//['1', '2', '3', '4', '5', '6', '7']

replace()

作用:
可以将字符串中指定内容替换为新的内容

参数:
1.被替换的内容,可以接收一个正则表达式作为参数
2.新的内容,    空串则为删除 ""

默认只会替换第一个
eg1:

var str = '12sd34nfu7dg5sv8dwndg';

var result = str.replace(/[a-z]/g,'@');
console.log(result);
//12@@34@@@7@@5@@8@@@@@
eg2:
var result2 = 'hello.  --a.. . ,, day n  i ce'.replace(/[,-\.\s]/g,'');
console.log(result2);
//helloadaynice

search()

作用:
可以搜索字符串中是否含有指定内容
如果搜索到指定内容,则会返回第一次出现的索引
如果没有搜索到则返回-1
它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串
serach()只会查找第一个,即使设置全局匹配也没用

eg:
var str = "123ASDzxc";

var result2 = str.search(/[0-9][2-3][A-z]/);

console.log(result2);//1

13.7常用正则表达式

1、校验数字的表达式

汉字:^[\u4e00-\u9fa5]{0,}$
英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符:[^~\x22]+

2、校验字符的表达式

数字:^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零和非零开头的数字:^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
非负整数:^\d+$ 或 ^[1-9]\d*|0$
非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$

3、特殊需求表达式

Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手机号码:^(13[0-9]|14[0-9]|15[0-9]|16[0-9]|17[0-9]|18[0-9]|19[0-9])\d{8}$ (由于工信部放号段不定时,所以建议使用泛解析 ^([1][3,4,5,6,7,8,9])\d{9}$)
电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$ 
国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7} 
18位身份证号码(数字、字母x结尾):^((\d{18})|([0-9x]{18})|([0-9X]{18}))$
帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
#强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$  
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$ 
钱的输入格式:
	1. 有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$ 
    2. 这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$ 
    3. 一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$ 
    4. 这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$ 
    5. 必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$ 
    6. 这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$ 
    7. 这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$ 
    8. 1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$ 
备注:这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
中文字符的正则表达式:[\u4e00-\u9fa5]
双字节字符:[^\x00-\xff]    (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s*\r    (可以用来删除空白行)
HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />    (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$)    (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
腾讯QQ号:[1-9][0-9]{4,}    (腾讯QQ号从10000开始)
中国邮政编码:[1-9]\d{5}(?!\d)    (中国邮政编码为6位数字)
IP地址:\d+\.\d+\.\d+\.\d+    (提取IP地址时有用)
IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))  (由@飞龙三少 提供,感谢共享)

Document Object Model

文档对象模型,通过DOM可以来任意来修改网页中各个内容

文档

        文档指的是网页,一个网页就是一个文档

对象

        对象指将网页中的每一个节点都转换为对象

        转换完对象以后,就可以以一种纯面向对象的形式来操作网页了

模型

        模型用来表示节点和节点之间的关系,方便操作页面

节点(Node)

节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点

虽然都是节点,但是节点的类型却是不同的

常用的节点

文档节点 (Document),代表整个网页

元素节点(Element),代表网页中的标签

属性节点(Attribute),代表标签中的属性

文本节点(Text),代表网页中的文本内容

14、DOM(Document Object Model)

14.1.DOM介绍

文档Document
-表示整个HTML网页文档

对象Object
-表示将网页中的每一部分都转换为一个对象

模型Model
-表示对象之间的关系

1、document对象

WINDOW对象的属性
代表整个网页,可以在页面中直接使用

2、model

<html>
		<head>
				<title>网页的标题</title>
		</head>
		<body>
				<a href="1.html">超链接</a>
		</body>
</html>

3、节点

节点node,是构成网页的最基本组成部分,网页中的每一部分都可以称为是一个节点

比如:html标签、属性、文本、注释、整个文档等都是一个节点。

文档节点:整个HTML文档
元素节点:HTML文档中的HTML标签
属性节点:元素的属性
文本节点:HTML标签中的文本内容

节点的属性:

14.2.DOM查询

1、获取DOM对象

DOCUMENT查询方法:
根据元素的id属性查询一个元素节点对象:document.getElementById("id属性值");
根据元素的name属性值查询一组元素节点对象:document.getElementsByName("name属性值");
作用:可以获取带有指定名称的集合
根据标签名来查询一组元素节点对象:(类数组)document.getElementsByTagName("标签名");

2、获取元素节点的属性

元素的属性:

读取元素节点的的属性:
语法:元素节点.属性名
alert(ele.type);

修改元素节点的属性:
语法:元素节点.属性名 = 属性值
ele.type = 'submit';

例子:
let ele = doucument.getElementsByTagName('input');
ele.name
ele.id
ele.value
ele.className

注意:class属性不能采用这种方式,
读取class属性时需要使用 元素节点.className


innerHTML
使用该属性可以获取或设置元素内部的HTML代码

3、innerHTML和innerText

这两个属性并没有在DOM标准定义,但是大部分浏览器都支持这两个属性

1、作用:
 innerHtml:获取标签内部的HTML代码,包括HTML标签
 	浏览器会解析设置的值为相应的DOM树
 
 innerText:获取标签内部的HTML代码,自动去除HTML标签
 	
 
 outerHTML:除了包含innerHTML全部内容外,还包含对象标签本身
 
2、读取标签内部的文本内容

如果使用这两个属性来设置标签内部的内容时,没有任何区别的

3、还可以使用innerHTML来修改内容
document.getElementById('X').innerHTML = '要修改的内容'
4、innerHTML对于自结束标签无意义

5、innerHTML所有浏览器都支持,innerText Firefox不支持

4、通过具体的元素节点来查询

通过标签名查询当前元素的指定后代元素
1、先找到父节点
2、通过父节点去找子节点

元素节点.getElementsByTagName()[0]

元素节点.getElementsByClassName()[0]

element.getElementById();


子节点包括标签元素中的文本,子元素只包含标签元素

元素节点.childNodes
获取当前元素的**所有子节点**
**会获取到空白的文本子节点**

childNodes属性会获取包括文本节点在内的所有节点
根据DOM标签标签间空白也会当成文本节点

注意:在IE8及以下的浏览器中,不会将空白文本当成子节点,
所以该属性在IE8中会返回4个子元素而其他浏览器是9个

获取指定子节点
元素节点.childNodes[i]


★元素节点.children
获取当前元素的**所有子元素**

获取指定元素
元素节点.children[i]

元素节点.firstChild
获取当前元素的**第一个子节点**,会获取到空白的文本子节点

元素节点.lastChild
获取当前元素的**最后一个子节点**

★元素节点.parentNode
获取当前元素的父元素

元素节点.previousSibling
获取当前元素的前一个兄弟节点(包括文本节点)

★元素节点.previousElementSibling获取前一个兄弟元素,
IE8及以下不支持

元素节点.nextSibling
获取当前元素的后一个兄弟节点(包括文本节点)

★元素节点.nextElementSibling
获取当前元素的后一个兄弟元素

firstElementChild获取当前元素的第一个子元素
firstElementChild不支持IE8及以下的浏览器,
如果需要兼容他们尽量不要使用

lastElementChild获取当前元素的最后一个子元素


元素.firstChild.nodeValue获取当前元素第一个孩子节点(文本节点)的文本内容

/文档节点和元素节点的nodevalue是null

14.3.DOM其它属性和方法

document.documentElement
**获取页面中html根元素**

//获取HTML根标签
let h = document.documentElement;
console.log(h);

document.body
获取页面中的body元素

document的属性body保存body的引用

获取body标签  body 是一个[object HTMLCollection]

 let all = document.getElementsByTagName('body')[0];
console.log(all);
        
let body = document.body;
console.log(body);
document.all
**获取页面中的所有元素结点**,相当于document.getElementsByTagName("*");

获取页面中所有的元素结点
let All = document.all;
console.log(All);//返回一个类数组

let All2 = document.getElementsByTagName('*');
console.log(All2);
document.getElementsByClassName()
**根据元素的class属性值查询一组元素节点对象**

    这个方法不支持IE8及以下的浏览器
document.querySelector()
**根据CSS选择器去页面中查询一个元素**
如果匹配到的元素有多个,则它会返回查询到的第一个元素

参数:选择器的字符串
/----------------------------------------
<ul class="sport">
    <li>足球</li>
    <li>篮球</li>
    <li>乒乓</li>
    <div>ll</div>
</ul>

//querySelector
let query = document.querySelector('.sport li');
console.log(query);
//<li>...</li>
document.querySelectorAll()
根据CSS选择器去页面中查询一组元素
会将匹配到所有元素封装到一个数组中返回,即使只匹配到一个

/---------------------------------------------
<ul class="sport">
    <li>足球</li>
    <li>篮球</li>
    <li>乒乓</li>
    <div>ll</div>
</ul>

//querySelectorAll
let query2 = document.querySelectorAll('.sport li');
console.log(query2);
//NodeList(3)[li,li,li]

14.4.DOM修改(增、删、改)

方法 描述
createTextNode()创建文本节点
appendChild()把新的子节点添加到指定节点
removeChild()删除子节点
replaceChild()替换子节点
insertBefore()在指定的子节点前面插入新的子节点
createElement()创建元素节点
1、父节点.appendChild(子节点)
 向父节点中添加指定的子节点

2、父节点.removeChild(子节点)
 删除指定的子节点
 #当不知道具体的父元素时,可以通过parentNode得到#
 语法:
 	子节点.parentNode.removeChild(子节点)
 

3、父节点.replaceChild(新节点,旧节点)
  使用一个新的节点去替换旧节点
 

4、父节点.insertBefore(新节点,旧节点)
  将一个新的节点插入到旧节点的前边

5、document.createElement("TagName")
  可以用于创建一个元素节点对象,
  它需要一个标签名作为参数,将会根据该标签名创建元素节点对象,并将创建好的对象作为返回值返回

6、document.createTextNode("textContent")
  可以根据文本内容创建一个文本节点对象

以上方法,实际就是改变了相应元素(标签)的innerHTML的值。

myClick("btn07",function(){  
//向city中添加广州  
    var city = document.getElementById("city");    
 /*  
使用innerHTML也可以完成DOM的增删改的相关操作  
 一般我们会两种方式结合使用  
*/  
//第一种、
    city.innerHTML += "<li>广州</li>";  

//第二种、
//创建一个li  
    var li = document.createElement("li");  
//向li中设置文本  
    li.innerHTML = "广州";  
//将li添加到city中  
    city.appendChild(li);  
});  

14.5.DOM对CSS的操作

读取和修改内联样式

使用style属性来操作元素的内联样式

$$
读取内联样式语法:元素节点.style.样式名
$$

例子:

元素节点.style.width

元素节点.style.height

注意:如果样式名中带有''-'',则需要将样式名修改为驼峰命名法将-去掉,然后后面的字母改成大写

比如: backgroundcolor => backgroundColor

         borderwidth => borderWidth

box1.style.backgroundColor ='red';
修改内联样式:

语法:
        元素节点.style.样式名 = '样式值'
box1.style.width ='250px';
通过style修改和读取的样式都是内联样式,由于内联样式的优先级比较高,
所以我们通过JS来修改的样式,往往会立即生效,

//通过style修改的样式,是修改的内联样式

<body>
    <div id="box1" style="width:100px;height:100px"></div>
    <button id="btn01">按钮1</button>
    <button id="btn02">按钮2</button>

    <script>
        let box1 = document.getElementById('box1');
        

    //若样式属性里有"-",则采用驼峰命名法
        // box1.style.backgroundColor ='red';

    //通过style修改的样式,是修改的内联样式
    let btn01 = document.getElementById('btn01');
    btn01.onclick = function(){
        box1.style.width ='250px';
        box1.style.height ='250px';
    }
    let btn02 = document.getElementById('btn02');
    btn02.onclick = function(){
        alert(box1.style.width);
    }
    </script>
</body>
**但是如果样式中设置了!important,则内联样式将不会生效。**

!important 作用:获取到最高的优先级(慎用)

读取元素的当前样式

正常浏览器 使用getComputedStyle()

getComputedStyle()
这个方法是window对象的方法,可以返回一个对象,这个对象中保存着当前元素生效样式
参数:
1.要获取样式的元素节点
2.可以传递一个伪元素,一般传null
例子:
获取元素的宽度
getComputedStyle(box , null)["width"];
通过该方法读取到样式都是只读的不能修改

IE8 使用currentStyle

currentStyle
语法:
元素节点.currentStyle.样式名
例子:
box.currentStyle["width"]
通过这个属性读取到的样式是只读的不能修改

实现兼容性

对象.属性不存在,不会报错,

如果直接寻找对象,(当前作用域到全局作用域)找不到会报错

/*  
* 定义一个函数,用来获取指定元素的当前的样式  
* 参数:  
* 		obj 要获取样式的元素  
* 		name 要获取的样式名
*
*该方法会返回一个对象,对象中封装了当前元素对应的样式
*
*可以通过(对象.样式名)|(对象[样式名])来读取样式
*
*如果获取的样式没有设置,则会获取到真实的值,而不是默认值,比如:没有设置width,不会获取到auto,而是一个长度
*/  
function getStyle(obj , name){  
//对象.属性不存在,不会报错,如果直接寻找对象,(当前作用域到全局作用域)找不到会报错  
    if(window.getComputedStyle){  
        //正常浏览器的方式,具有getComputedStyle()方法  
        return getComputedStyle(obj , null)[name];  
    }else{  
        //IE8的方式,没有getComputedStyle()方法  
        return obj.currentStyle[name];  
    }  
//简写
    //return window.getComputedStyle?getComputedStyle(obj , null)[name]:obj.currentStyle[name];			  
}  

其他的样式相关的属性

注意:以下样式都是只读的,未指明偏移量都是相对于当前窗口左上角

clientHeight
元素的可见高度,包括元素的内容区和内边距的高度
clientWidth
元素的可见宽度,包括元素的内容区和内边距的宽度
clientLeft
左边框的宽度
clientTop
上边框的宽度

#不需要带px,返回的是一个数字,可以直接进行计算

offsetHeight
整个元素的高度,包括内容区、内边距、边框
offfsetWidth
整个元素的宽度,包括内容区、内边距、边框
offsetParent
当前元素的定位父元素
离他最近的开启了定位的祖先元素,如果所有的元素都没有开启定位,则返回body
offsetLeft
offsetTop
当前元素和定位父元素之间的偏移量
offsetLeft水平偏移量 
offsetTop垂直偏移量

scrollHeight
scrollWidth
获取元素滚动区域的高度和宽度
(文档内容实际高度,包括超出视窗的溢出部分)

判断滚动条是否滚动到底
垂直滚动条
scrollHeight -scrollTop = clientHeight

水平滚动
scrollWidth -scrollLeft = clientWidth

可写

scrollTop
scrollLeft
获取元素垂直和水平滚动条滚动的距离

scrollHeight、scrollTop、clientHeight三者的关系:

事件(Event)

事件

事件指的是用户和浏览器之间的交互行为。比如:点击按钮、关闭窗口、鼠标移动。。。

#我们可以为事件来绑定回调函数来响应事件

绑定事件的方式

1.可以在标签的事件属性中设置相应的JS代码 例子:

<button onclick="js代码。。。">按钮</button> 
//结构和行为耦合,不方便维护

2.可以通过为对象的指定事件属性设置回调函数的形式来处理事件 例子:

<button id="btn">按钮</button>  
<script>  
    var btn = document.getElementById("btn");  
    btn.onclick = function(){  
  
    };  
</script>  

文档的加载

浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行
如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载
此时将会无法正常获取到DOM对象,导致DOM操作失败
解决方式一:
可以将js代码编写到body里边

将JS代码编写到页面的下部,可以在页面加载完成后,直接执行JS代码

<body>  
<button id="btn">按钮</button>  
  
<script>  
	var btn = document.getElementById("btn");  
		btn.onclick = function(){  
		  
	};  
</script>  
</body>  

解决方式二:

onload事件会在整个页面加载完成之后才触发

为Window绑定一个onload事件
	该事件对应的响应函数将会在页面加载完成之后再执行
	可以确保代码执行时,DOM对象已经加载完毕了
	
	将js代码编写到window.onload = function(){}中
window.onload 对应的回调函数会在整个页面加载完毕以后才执行,
<script>  
 window.onload = function(){  
    var btn = document.getElementById("btn");  
        btn.onclick = function(){  
       };  
   };  
</script>	

事件对象(event)

当响应函数被调用时,浏览器每次都会将一个事件对象作为实参传递进响应函数中,这个事件对象中封装了当前事件的相关信息,比如:鼠标的坐标,键盘的按键,鼠标的按键,滚轮的方向。。

可以在响应函数中定义一个形参,来使用事件对象,但是在IE8以下浏览器中事件对象没有作为实参传递,而是作为window对象的属性保存

例子:

元素.事件 = function(event){  
    event = event || window.event;  
};  
  
元素.事件 = function(e){  
	e = e || event;  
	  
};  

获取到鼠标的坐标

clientX和clientY

用于获取鼠标在当前的可见窗口的坐标 div的偏移量,是相对于整个页面的

pageX和pageY

可以获取鼠标相对于当前页面的坐标

但是这个两个属性在IE8中不支持,所以如果需要兼容IE8,则不要使用

var left = event.clientX; v

ar top = event.clientY;

事件的冒泡(Bubble)

事件的冒泡指的是事件向上传导当后代元素上的事件被触发时,将会导致其祖先元素上的同类事件也会触发。 事件的冒泡大部分情况下都是有益的,如果需要取消冒泡,则需要使用事件对象来取消 可以将事件对象的cancelBubble设置为true,即可取消冒泡 例子:

元素.事件 = function(event){ 
 //解决事件对象的兼容性问题
    event = event || window.event;
 //在IE8中,响应函数被触发时,浏览器不会传递事件对象
 在IE8及以上的浏览器中,是将事件对象作为window对象的属性保存的
    event.cancelBubble = true;  
};  

事件的委派

事件委派:JS事件委托(事件代理) (biancheng.net)

指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。

事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能

我们希望,只绑定一次事件,即可应用到多个的元素上,即使元素是后添加的

我们可以尝试将其绑定给元素的共同的祖先元素

target : event中的target表示的触发事件的对象

事件的绑定

addEventListener() 通过这个方法也可以为元素绑定响应函数 参数: 1.事件的字符串,不要on 2.回调函数,当事件触发时该函数会被调用 3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false

使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数, 这样当事件被触发时,响应函数将会按照函数的绑定顺序执行

这个方法不支持IE8及以下的浏览器

btn01.addEventListener("click",function(){  
	alert(1);  
},false);  
  
btn01.addEventListener("click",function(){  
	alert(2);  
},false);	

attachEvent()

在IE8中可以使用attachEvent()来绑定事件 参数: 1.事件的字符串,要on 2.回调函数

这个方法也可以同时为一个事件绑定多个处理函数, 不同的是它是后绑定先执行,执行顺序和addEventListener()相反

btn01.attachEvent("onclick",function(){  
alert(1);  
});  
  
btn01.attachEvent("onclick",function(){  
alert(2);  
});	  
//定义一个函数,用来为指定元素绑定响应函数  
/*  
			 * addEventListener()中的this,是绑定事件的对象  
			 * attachEvent()中的this,是window  
			 *  需要统一两个方法this  
			 */  
/*  
			 * 参数:  
			 * 	obj 要绑定事件的对象  
			 * 	eventStr 事件的字符串(不要on)  
			 *  callback 回调函数  
			 */  
function bind(obj , eventStr , callback){  
    if(obj.addEventListener){  
        //大部分浏览器兼容的方式  
        obj.addEventListener(eventStr , callback , false);  
    }else{  
        /*  
					 * this是谁由调用方式决定  
					 * callback.call(obj)  
					 */  
        //IE8及以下  
        obj.attachEvent("on"+eventStr , function(){  
            //在匿名函数中调用回调函数  
            callback.call(obj);  
        });  
    }  
}  

事件的传播

关于事件的传播网景公司和微软公司有不同的理解 微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件, 然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件, 然后在向内传播给后代元素

W3C综合了两个公司的方案,将事件传播分成了三个阶段

1.捕获阶段 在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件

2.目标阶段 事件捕获到目标元素,捕获结束开始在目标元素上触发事件

3.冒泡阶段 事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件

如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true 一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false

IE8及以下的浏览器中没有捕获阶段

常用事件

鼠标事件

onmouseover 移入某元素就触发,移入或移出子元素将再次被触发
onmousemove 在绑定的元素上移动时,被触发

拖拽事件(onmousemove)

<!DOCTYPE html>  
    <html>  
    <head>  
    <meta charset="UTF-8">  
        <title></title>  
<style type="text/css">  
  
    #box1{  
width: 100px;  
height: 100px;  
background-color: red;  
position: absolute;  
}  
  
#box2{  
width: 100px;  
height: 100px;  
background-color: yellow;  
position: absolute;  
  
left: 200px;  
top: 200px;  
}  
  
    </style>  
  
<script type="text/javascript">  
  
    window.onload = function(){  
 /*  
 * 拖拽box1元素  
 *  - 拖拽的流程  
 * 	1.当鼠标在被拖拽元素上按下时,开始拖拽   onmousedown  
 * 	2.当鼠标移动时被拖拽元素跟随鼠标移动     onmousemove  
 * 	3.当鼠标松开时,被拖拽元素固定在当前位置  onmouseup  
 */  
  
    //获取box1  
    var box1 = document.getElementById("box1");  
    var box2 = document.getElementById("box2");  
    var img1 = document.getElementById("img1");  
  
    //开启box1的拖拽  
    drag(box1);  
    //开启box2的  
    drag(box2);  
  
    drag(img1);  
  
};  
  
/*  
* 提取一个专门用来设置拖拽的函数  
* 参数:开启拖拽的元素  
*/  
function drag(obj){  
    //当鼠标在被拖拽元素上按下时,开始拖拽  onmousedown  
    obj.onmousedown = function(event){  
  
//设置box1捕获所有鼠标按下的事件  
 /*  
* setCapture()  
* 	- 只有IE支持,但是在火狐中调用时不会报错,  
* 		而如果使用chrome调用,会报错  
*/  
        /*if(box1.setCapture){  
				box1.setCapture();  
		 }*/  
		 
        obj.setCapture && obj.setCapture();  
  
  
        event = event || window.event;  
        //div的偏移量 鼠标.clientX - 元素.offsetLeft  
        //div的偏移量 鼠标.clientY - 元素.offsetTop  
        var ol = event.clientX - obj.offsetLeft;  
        var ot = event.clientY - obj.offsetTop;  
  
  
        //为document绑定一个onmousemove事件  
        document.onmousemove = function(event){  
            event = event || window.event; 
            
            //当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove  
            //获取鼠标的坐标  
            var left = event.clientX - ol;  
            var top = event.clientY - ot;  
  
            //修改box1的位置  
            obj.style.left = left+"px";  
            obj.style.top = top+"px";  
  
        };  
  
        //为document绑定一个鼠标松开事件  
        document.onmouseup = function(){  
            //当鼠标松开时,被拖拽元素固定在当前位置	onmouseup  
            //取消document的onmousemove事件  
            document.onmousemove = null;  
            //取消document的onmouseup事件  
            document.onmouseup = null;  
            //当鼠标松开时,取消对事件的捕获  
            obj.releaseCapture && obj.releaseCapture();  
        };  
  
 /*  
* 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,  
* 	此时会导致拖拽功能的异常,这个是浏览器提供的默认行为,  
* 	如果不希望发生这个行为,则可以通过return false来取消默认行为  
*   
* 但是这招对IE8不起作用  
*/  
        return false;  
    };  
}  
  
  
</script>  
</head>  
<body>  
  
    我是一段文字  
  
<div id="box1"></div>  
  
<div id="box2"></div>  
  
<img src="img/an.jpg" id="img1" style="position: absolute;"/>  
    </body>  
</html>  

滚轮事件

onwheel都支持

<!DOCTYPE html>  
    <html>  
    <head>  
    <meta charset="UTF-8">  
        <title></title>  
<style type="text/css">  
  
    #box1{  
width: 100px;  
height: 100px;  
background-color: red;  
}  
  
    </style>  
<script type="text/javascript">  
  
    window.onload = function(){  
  
  
    //获取id为box1的div  
    var box1 = document.getElementById("box1");  
  
    //为box1绑定一个鼠标滚轮滚动的事件  
    /*  
				 * onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发,  
				 * 	但是火狐不支持该属性  
				 *   
				 * 在火狐中需要使用 DOMMouseScroll 来绑定滚动事件  
				 * 	注意该事件需要通过addEventListener()函数来绑定  
				 */  
  
  
    box1.onmousewheel = function(event){  
  
        event = event || window.event;  
  
  
        //event.wheelDelta 可以获取鼠标滚轮滚动的方向  
        //向上滚 120   向下滚 -120  
        //wheelDelta这个值我们不看大小,只看正负  
  
        //alert(event.wheelDelta);  
  
        //wheelDelta这个属性火狐中不支持  
        //在火狐中使用event.detail来获取滚动的方向  
        //向上滚 -3  向下滚 3  
        //alert(event.detail);  
  
  
        /*  
					 * 当鼠标滚轮向下滚动时,box1变长  
					 * 	当滚轮向上滚动时,box1变短  
					 */  
        //判断鼠标滚轮滚动的方向  
        if(event.wheelDelta > 0 || event.detail < 0){  
            //向上滚,box1变短  
            box1.style.height = box1.clientHeight - 10 + "px";  
  
        }else{  
            //向下滚,box1变长  
            box1.style.height = box1.clientHeight + 10 + "px";  
        }  
  
        /*  
					 * 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false  
					 * 需要使用event来取消默认行为event.preventDefault();  
					 * 但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错  
					 */  
        event.preventDefault && event.preventDefault();  
  
  
        /*  
					 * 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,  
					 * 这是浏览器的默认行为,如果不希望发生,则可以取消默认行为  
					 */  
        return false;  
  
  
  
  
    };  
  
    //为火狐绑定滚轮事件  
    bind(box1,"DOMMouseScroll",box1.onmousewheel);  
  
  
};  
  
  
function bind(obj , eventStr , callback){  
    if(obj.addEventListener){  
        //大部分浏览器兼容的方式  
        obj.addEventListener(eventStr , callback , false);  
    }else{  
        /*  
					 * this是谁由调用方式决定  
					 * callback.call(obj)  
					 */  
        //IE8及以下  
        obj.attachEvent("on"+eventStr , function(){  
            //在匿名函数中调用回调函数  
            callback.call(obj);  
        });  
    }  
}  
  
</script>  
</head>  
<body style="height: 2000px;">  
  
    <div id="box1"></div>  
  
</body>  
</html>  

键盘事件

键盘事件:

onkeydown 按键被按下

对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快,这种设计是为了防止误操作的发生。

onkeyup 按键被松开

键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document

keyCode

可以通过keyCode来获取按键的编码 通过它可以判断哪个按键被按下 除了keyCode,事件对象中还提供了几个属性

altKey

ctrlKey

shiftKey 这个三个用来判断alt ctrl 和 shift是否被按下

如果按下则返回true,否则返回false

console.log(event.keyCode);  
//判断一个y是否被按下  
//判断y和ctrl是否同时被按下  
if(event.keyCode === 89 && event.ctrlKey){  
	console.log("ctrl和y都被按下了");  
}  
input.onkeydown = function(event) {  
    event = event || window.event;  
    //数字 48 - 57  
    //使文本框中不能输入数字  
    if(event.keyCode >= 48 && event.keyCode <= 57) {  
        //在文本框中输入内容,属于onkeydown的默认行为  
        //如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中  
        return false;  
    }  
};  

BOM

浏览器对象模型(browser object model)

BOM可以使我们通过JS来操作浏览器

在BOM中为我们提供了一组对象,用来完成对浏览器的操作

BOM对象

Window

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

Navigator

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

Location

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

History

代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录

由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页

而且该操作只在当次访问时有效

Screen

代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息

这些BOM对象在浏览器中都是作为window对象的属性保存的, 可以通过window对象来使用,也可以直接使用

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

由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了

一般我们只会使用userAgent来判断浏览器的信息, userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容, 不同的浏览器会有不同的userAgent

火狐的userAgent Mozilla5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko20100101 Firefox50.0

Chrome的userAgent Mozilla5.0 (Windows NT 6.1; Win64; x64) AppleWebKit537.36 (KHTML, like Gecko) Chrome52.0.2743.82 Safari537.36

IE8 Mozilla4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)

IE9 Mozilla5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)

IE10 Mozilla5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)

IE11 Mozilla5.0 (Windows NT 6.1; WOW64; Trident7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko 在IE11中已经将微软和IE相关的标识都已经去除了,所以我们基本已经不能通过UserAgent来识别一个浏览器是否是IE了

alert(navigator.appName);  
  
var ua = navigator.userAgent;  
  
console.log(ua);  
  
if(firefoxi.test(ua)){  
alert("你是火狐!!!");  
}else if(chromei.test(ua)){  
alert("你是Chrome");  
}else if(msiei.test(ua)){  
alert("你是IE浏览器~~~");  
}else if("ActiveXObject" in window){  
alert("你是IE11,枪毙了你~~~");  
}  

History

对象可以用来操作浏览器向前或向后翻页

length

        属性,可以获取到当成访问的链接数量

back()

        可以用来回退到上一个页面,作用和浏览器的回退按钮一样

forward()

        可以跳转下一个页面,作用和浏览器的前进按钮一样

go()

        可以用来跳转到指定的页面

        它需要一个整数作为参数

        1:表示向前跳转一个页面 相当于forward()

        2:表示向前跳转两个页面

        -1:表示向后跳转一个页面

        -2:表示向后跳转两个页面

Location

该对象中封装了浏览器的地址栏的信息

如果直接打印location,则可以获取到当前地址栏的信息(当前页面的完整路径)

alert(location);

如果直接将location属性修改为一个完整的路径,或相对路径

则我们页面会自动跳转到该路径,并且会生成相应的历史记录
 

​
location = "http:www.baidu.com";

location = "01.BOM.html";

​

assign() 用来跳转到其他的页面,作用和直接修改location一样

reload() 用于重新加载当前页面,作用和刷新按钮一样

如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面

location.reload(true);

replace()

可以使用一个新的页面替换当前页面,调用完毕也会跳转页面

不会生成历史记录不能使用回退按钮回退

window

定时器

setInterval() 定时调用

可以将一个函数,每隔一段时间执行一次

参数:

1.回调函数,该函数会每隔一段时间被调用一次

2.每次调用间隔的时间,单位是毫秒

返回值: 返回一个Number类型的数据 ,这个数字用来作为定时器的唯一标识

clearInterval() 可以用来关闭一个定时器

方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器

clearInterval() 可以接收任意参数, 如果参数是一个有效的定时器的标识,则停止对应的定时器 如果参数不是一个有效的标识,则什么也不做

var num = 1;  
var timer = setInterval(function() {  
	count.innerHTML = num++;  
	if(num == 11) {  
		//关闭定时器  
		clearInterval(timer);  
	}  
}, 1000);  

setTimeout 延时调用

延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次

延时调用和定时调用的区别定时调用会执行多次,而延时调用只会执行一次

延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择

var timer = setTimeout(function(){

        console.log(num++);

},3000);

使用clearTimeout()来关闭一个延时调用

clearTimeout(timer);

#类的操作

直接修改元素的类css:

通过style属性来修改元素的样式,每修改一个样式,浏览器就需要重新渲染一次页面。 这样的执行的性能是比较差的,而且这种形式当我们要修改多个样式时,也不太方便

我们希望一行代码,可以同时修改多个样式

我们可以通过修改元素的class属性来间接的修改样式。这样一来,我们只需要修改一次,即可同时修改多个样式,浏览器只需要重新渲染页面一次,性能比较好, 并且这种方式,可以使表现和行为进一步的分离

box.className += " b2";	//注意有空格,添加class属性  
//定义一个函数,用来向一个元素中添加指定的class属性值  
/*  
 * 参数:  
 * 	obj 要添加class属性的元素  
 *  cn 要添加的class值  
 * 	  
 */  
function addClass(obj, cn) {  
	if (!hasClass(obj, cn)) {  
		obj.className += " " + cn;  
	}  
}  
/*  
 * 判断一个元素中是否含有指定的class属性值  
 * 	如果有该class,则返回true,没有则返回false  
 * 	  
 */  
function hasClass(obj, cn) {  
	var reg = new RegExp("\\b" + cn + "\\b");  
	return reg.test(obj.className);  
}  
/*  
 * 删除一个元素中的指定的class属性  
 */  
function removeClass(obj, cn) {  
	//创建一个正则表达式  
	var reg = new RegExp("\\b" + cn + "\\b");  
	//删除class  
	obj.className = obj.className.replace(reg, "");  
}  
/*  
 * toggleClass可以用来切换一个类  
 * 	如果元素中具有该类,则删除  
 * 	如果元素中没有该类,则添加  
 */  
function toggleClass(obj , cn){	  
	//判断obj中是否含有cn  
	if(hasClass(obj , cn)){  
		//有,则删除  
		removeClass(obj , cn);  
	}else{  
		//没有,则添加  
		addClass(obj , cn);  
	}  
}  

JSON

JavaScript Object Notation JS对象表示法

JSON 格式

  1. 复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。

  2. 原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和null不能使用NaN, Infinity, -Infinityundefined)。

  3. 字符串必须使用双引号表示,不能使用单引号。

  4. 对象的键名必须放在双引号里面。

  5. 数组或对象最后一个成员的后面,不能加逗号。

JS中的对象只有JS自己认识,其他的语言都不认识

JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别, 并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互

JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号 ,其他的和JS语法一致

JSON分类:

         1.对象 {}         2.数组 []

JSON中允许的值: 1.字符串 2.数值 3.布尔值 4.null 5.对象 6.数组

举例:

var arr = '[1,2,3,"hello",true]';  
			  
var obj2 = '{"arr":[1,2,3]}';  
  
var arr2 ='[{"name":"孙悟空","age":18,"gender":"男"},{"name":"孙悟空","age":18,"gender":"男"}]';  

JSON工具类

json字符串 转换 js对象

JSON.parse()

可以将以JSON字符串转换为js对象

它需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回

var o = JSON.parse(json);

var o2 =JSON.parse(arr);

var obj3 = {name:"猪八戒" , age:28 , gender:"男"};

JS对象 转换 json字符串

JSON.stringify() -ify/fy,表示"使……化。

可以将一个JS对象转换为JSON字符串

需要一个js对象作为参数,会返回一个JSON字符串

var str = JSON.stringify(obj3);

console.log(str);

JSON这个对象在IE7及以下的浏览器中不支持,所以在这些浏览器中调用时会报错

other

localStorage

只读的localStorage 属性允许你访问一个Document 源(origin)的对象 Storage;其存储的数据能在跨浏览器会话保留。localStorage 类似 sessionStorage,但其区别在于:存储在 localStorage 的数据可以长期保留;而当页面会话结束——也就是说,当页面被关闭时,存储在 sessionStorage 的数据会被清除 。

localStorage 中的键值对总是以字符串的形式存储。

存储的键值对总是以 UTF-16 DOMString 的格式所存储,其使用两个字节来表示一个字符。对于对象、整数 key 值会自动转换成字符串形式。

语法   

myStorage = localStorage;

方法

setItem()        向本地增加一个记录

localStorage.setItem('myCat', 'Tom');
//key:keyValue

getItem()        读取localStorage项

let cat = localStorage.getItem('myCat');

removeItem()        移除localStorage项

localStorage.removeItem('myCat');

clear()        移除所有的localStorage项

// 移除所有
localStorage.clear();

sessionStorage

存储在 sessionStorage 里面的数据在页面会话结束时会被清除。

// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');

// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');

// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');

// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();

返回值

一个Storage对象

eval()

eval()函数会将传入的字符串当做 JavaScript 代码进行执行并将执行结果返回。如果返回值为空,则返回 undefined

如果使用eval()执行的字符串中含有{},它会将{}当成是代码块 如果不希望将其当成代码块解析,则需要在字符串前后各加一个()

eval()这个函数的功能很强大,可以直接执行一个字符串中的js代码, 但是在开发中尽量不要使用,首先它的执行性能比较差,然后它还具有安全隐患   ,只作了解,不要使用             

var str = '{"name":"孙悟空","age":18,"gender":"男"}';  
var obj = eval("("+str+")");  

编码

\u四位编码

<!DOCTYPE html>  
<html>  
	<head>  
		<meta charset="UTF-8">  
		<title></title>  
		<script type="text/javascript">  
			  
			/*  
			 * 在字符串中使用转义字符输入Unicode编码  
			 * 	\u四位编码  
			 */  
			console.log("\u2620");	  
		</script>  
	</head>  
	<body>		  
		<!--在网页中使用Unicode编码  
			&#编码; 这里的编码需要的是10进制  
		-->  
		<h1 style="font-size: 200px;">&#9760;</h1>  
		<h1 style="font-size: 200px;">&#9856;</h1>		  
	</body>  
</html>  

原生js

原生js实现复制内容到剪切板

copy() {  
    const input = document.createElement("input");  
    document.body.appendChild(input);  
    input.setAttribute("value",this.solution.code);  
    input.select();  
    if (document.execCommand("copy")) {  
        document.execCommand("copy");  
        // console.log("复制成功");  
    }  
    document.body.removeChild(input);  
}  

参考链接:

 尚硅谷视频

 MDN

菜鸟教程

w3school 在线教程

以及其中引用的链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值