JavaScript学习笔记

it2026-09-26  13

JavaScript学习笔记

JS学习笔记

JavaScriptJS简介1.语言的发展:2.JS起源3.ECMAScript标准(文档)4.实现5.JS特点 JS编写的位置输出语句基本语法字面量与变量字面量变量标识符 数据类型六种数据类型1.String字符串2.Number数值3.Boolean布尔值(true ,false)4.Null空值5.Undefined 未定义引用数据类型 类型转换转换为String方式一(强制类型转换)方式二(强制类型转换)方式三(隐式的类型转换) 转换为Number(有局限)方式一(强制类型转换)使用Number()函数方式二(强制类型转换):使用parseInt()或parseFloat()函数方式三(隐式的类型转换) 其他进制的数字转换为布尔值方式一(强制类型转换)方式二(隐式类型转换) 基础语法运算符,即操作符typeof运算符算数运算符:+ - * / %+一元运算符一元+(正号)一元-(负号)自增自减 逻辑运算符 非与或赋值运算符关系运算符:比较两值大小,关系成立返回true,否则返回false相等运算符三元运算符(条件运算符)运算符的优先级 流程控制语句条件判断语句条件分支语句 switch循环语句break continue 对象(Object)引用数据类型对象的分类创建对象属性名和属性值调用对象的方法 枚举对象中的属性(解决不知对象中有那些属性的问题)in运算符栈内存(先进后出)、堆内存(先进先出)对象字面量函数(Function)函数的参数函数的返回值返回值的类型(任意)立即执行函数 全局作用域(scope)1.全局作用域变量、函数的声明提前2.函数作用域 函数的方法this(上下文对象)arguments实参工厂方法创建对象 构造函数构造函数修改 原型(prototype)toString方法垃圾回收(GC) 数组(对象)——>存储性能好数组的操作数组字面量数组的方法slice(start,[end])splice()删除数组的指定元素conact()join([splitor])reverse()sort() 遍历数组forEach 常用类和方法包装类DateMath字符串的相关的方法 正则表达式语法字符串和正则相关的方法 DOM(Document Object Model)DOM操作事件(Event)文档的加载DOM 查询document对象的其他的属性和方法DOM增删改DOM对CSS的操作获取元素当前的样式其他的样式相关的属性 事件(Event)事件对象事件的冒泡(Bubble)事件的委派事件的绑定事件的传播常用事件鼠标事件键盘事件 BOMNavigatorHistoryLocationwindow定时器延时调用 JSON#原生js otherlocalStorageeval() 注意事项

JavaScript

JS简介

1.语言的发展:

类型语言纸带机机器语言汇编语言符号语言现代语言高级语言

2.JS起源

JS起源于1995年,用于处理网页中的前端验证。

前端验证:当网上冲浪越来越流行时,对于开发客户端脚本的需求也逐渐增大。此时,大部分因特网用户还仅仅通过 28.8 kbit/s(28kbit上传,28kbit下载) 的调制解调器连接到网络,即便这时网页已经不断地变得更大和更复杂。而更加加剧用户痛苦的是,仅仅为了简单的表单有效性验证,就要与服务器进行多次地往返交互。设想一下,用户填完一个表单,点击提交按钮,等待了 30 秒的处理后,看到的却是一条告诉你忘记填写一个必要的字段。这些类似的场景,在本地就可以很好的解决掉,而不需要服务器来处理,也就更进一步的促进了JS的发展和成熟。 JS与Javascript的区别:链接: link.

3.ECMAScript标准(文档)

JavaScript引擎是执行JavaScript代码的程序或解释器。javaScript引擎可以实现为标准解释器或即时编译器,它以某种形式将JavaScript编译为字节码。

浏览器JS引擎实现方式开发公司FireFoxSpiderMonkey(蜘蛛猴)由Mozilla基金会与志愿者开发Chromev8(开源)由Google开发Internet ExplorerJScript/chakraMicrosoft

v8会把js代码转换为高效的机器码,而不在是依赖于解释器去执行。 FireFox是Navigator浏览器(网景公司)前身。

4.实现

5.JS特点

–解释型语言(不用编译) –类似于C和Java的语法结构 –动态语言 –基于原型的面向对象

JS编写的位置

1.可以编写到标签的指定属性中

// 可以编写到标签的指定属性中 <button onclick="alert('hello');">按钮</button> <a href="javascript:alert('aa');">超链接</a>

2.可以编写到script标签中

// 可以编写到script标签中中 <script type="text/javascript"></script>

2.可以将代码编写到外部的js文件中,然后通过标签将其引入

// 可以编写到script标签中中 <script type="text/javascript" src="文件路径"></script>

写在外部文件中,可以在不同的界面中同时引用,也可以利用到浏览器的缓存机制。 缓存机制:就是把一个已经请求过的web资源(如html页面,图片,JS,数据)拷贝一份放在浏览器中。缓存会根据进来的请求保存输入内容的副本。当下一个请求到来的时候,如果是相同的URL,浏览器会根据缓存机制决定是直接使用副本响应访问请求当(未超过缓存副本的有效期,304状态码)还是向源服务器再次发起请求(200)。

使用缓存机制原因 (1)减少网络带宽消耗 (2)降低服务器压力 (3)减少网络延迟 但缓存机制对开发者并不友好,因为当你更新页面后,但浏览器页面并未发生变化。 取消缓存机制:link.

输出语句

1.弹出警示框

// 弹出警示框 alert("哥,你真帅");

2.向控制台输出内容

//在页面中输出内容 console.log("哥,你真帅");

3.在页面输出内容

//在页面中输出内容 document.write("哥,你真帅");

基本语法

/* */多行注释。//单行注释。JS中严格区分大小写。JS会忽略多个空格与换行,所以可以利用其对代码进行美化。JS中每一条语句以分号结尾。 如果不写,浏览器会自动添加,但会消耗系统资源,有时系统会加错分号。

字面量与变量

字面量

字面量:不可改变的值 可直接使用,但一般不会直接使用。

// a 是变量,123是字面量 var a =123; // a是变量,“hello”是字面量 var a="hello";

变量

用以保存字面量。 声明变量 :使用关键字var 可通过变量对字面量进行描述。

标识符

在JS中可由自己命名的变量名、函数名、属性名。 JS底层保存标识符时实际采用Unicode编码。

规则:标识符中可以含字母、number、_、$。标识符不可以数字开头。不能为ES中的关键字或保留字采用驼峰命名法,首字母小写,每个单词的开头字母大写,其余字母小写。

数据类型

六种数据类型

前五种为基本数据类型,Object为引用数据类型

1.String字符串

单引号、双引号都可以,但不要混用在字符串种使用\作为转义字符 // 我说“今天天气不错” var str="我说\"今天天气不错\""; \n 换行 \t 空格制表符 \\表示\

2.Number数值

所有的数值都是Number类型,包括整数和浮点数。 运算符:typeof 检查一个变量的类型 语法: typeof +变量

// 1.7976931348623157e+308 JS种表示数字的最大值 //5e-324 0以上的最小值 alert(Number.MAX_VALUE); alert(Number.MIN_VALUE);

Infinity:正无穷。 用typeof 检查Infinity也会返回Number

NAN是一个特殊的数字,也会返回NumberNaN:Not a number 不是个数字 的 数字类型,一旦写程序出现NaN,那么肯定进行了非法的运算操作。 // NAN var a="abc"*"acd"; console.log(a); 使用JS进行浮点运算,就可能得到一个不精确的结果,不要用JS进行对精确度要求较高的运算。 // 0.30000000000000004 var c=0.1+0.2; console.log(c);

3.Boolean布尔值(true ,false)

使用typeof检查一个布尔值时,会返回"boolean"

4.Null空值

Null类型值只有一个:null 用来表示一个空的对象

// 返回object var c=null console.log(typeof c);

5.Undefined 未定义

Undefined只有一个:undefined

// 返回undefined ,已声明,未赋值 var c; console.log(typeof c);

引用数据类型

Object 对象

类型转换

转换为String

方式一(强制类型转换)

调用被转换数据的toString()方法,不会改变原变量 只能将String、Number、Boolean类型转换为String

// string var a=123; var b=a.toString(); alert(typeof b);;

方式二(强制类型转换)

调用String()函数,将被转换数据作为参数传给数据

// string var a=123; var b=String(a); alert(typeof b);;

使用String()函数,对于Number和Boolean实际上就是调用toString()方法。对于null值,直接转换为字符串"null",对于undefined直接转换为字符串"undefined"

方式三(隐式的类型转换)

为任意的数据类型 +""

// string 123 var a=123; var b=a+""; alert(typeof b);;

转换为Number(有局限)

无toNumber()方法

方式一(强制类型转换)使用Number()函数

1.字符串——>数字 如果为纯数字的字符串,直接转 如果存在非数字的字符串,转换为NAN 如果为空的字符串或全是空格,转换为0 2.布尔——>数字 true转为1,false转为0。 3.Null——>数字 输出0 4.Undefined——>数字 NaN

方式二(强制类型转换):使用parseInt()或parseFloat()函数

对于字符串转数字 // 123 number var a="123px"; a=parseInt(a); console.log(a); console.log(typeof a); // 123.456 number var a="123.456.7"; a=parseFloatt(a); console.log(a); console.log(typeof a); 对于非字符串转数字使用parseInt()或parseFloat()会先将其转换为String,然后再操作。 // NaN number var a=true; a=parseInt(a); console.log(a); console.log(typeof a);

方式三(隐式的类型转换)

使用一元的+来进行隐式的类型转换

// number 123 var a="123"; a=+a; console.log(typeof a); console.log(a);

其他进制的数字

在JS中,如需表示16进制数字,以0X开头 // 16 var a=0x10; console.log(a) 八进制,以0开头二进制,以0b开头,并非所有的浏览器支持。 像“070”这种字符串,有时浏览器会当8进制进行解析,有时会当作10进制来解析。 解决方法: // 70 var a="070"; a=parseInt(a,10); console.log(a);

转换为布尔值

方式一(强制类型转换)

对象转布尔字符串转布尔 除了null,其余都为true。 // boolean true var a="true"; a=Boolean(a); console.log(typeof a); console.log(a); 数字转布尔 当a = 0或a = NaN时为false,其余都为true。 // boolean true var a=123; a=Boolean(a); console.log(typeof a); console.log(a); null转布尔 // boolean false var a=null; a=Boolean(a); console.log(typeof a); console.log(a); undefined转布尔 // boolean false var a=undefined; a=Boolean(a); console.log(typeof a); console.log(a);

方式二(隐式类型转换)

为任意的类型做两次非运算,即可将其转为布尔值。

// boolean true var a=undefined; a=!!a; console.log(typeof a); console.log(a);

基础语法

运算符,即操作符

typeof运算符

获得一个值的类型,将该值类型以字符串形式返回.

// number var a=123; console.log(typeof a);

算数运算符:+ - * / %+

(1)加法运算

//1 2 var result=true+false; console.log(result); var s=2+null; console.log(s);

任何数与NaN做运算结果都是NaN.

//123456 string var result="123"+"456"; console.log(result); console.log( typeof result);

任何值和字符串做加法运算都会先转成字符串,然后与字符串做拼串操作。可以利用该特点将任意类型转换为String,由浏览器自动完成,实际也是调用String()函数

//123hello string var result=123+"hello"; console.log(result); console.log( typeof result); //string var c=123; c=c+""; console.log(typeof c); //33 string 123 string var c=1+2+"3"; console.log( c); console.log(typeof c); c="1"+2+3; console.log( c); console.log(typeof c);

(2)减法运算 除字符串加法,其余皆为转为Number计算

//c=99 var c=100-"1"; console.log( c);

(3)乘法运算 Number类型值与undefined做乘法运算,结果为NaN.

//2NaN NaN var c=2*undefined; console.log( c); var b="2"*undefined; cosole.log(b);

可以利用任何值在做减法、乘法、除法运算时会自动转为Number这一特点做隐式类型转换,原理与Number()函数一样。

//122 number var c="123"; c=c-1; console.log(c);

(4)取模运算

一元运算符

一元+(正号)

–对于Number类型,不会对值产生任何影响

//123 var a=123; a=+a; console.log(a);

–任意数据类型使用+号来将其转换为number,原理与Number()函数一样

//123 number var a="123"; a=+a; console.log(a); //6 var a==1++"2"+3; console.log(a);

一元-(负号)

–符号取反

//-123 var a=123; a=-a; console.log(a);

–对于非Number类型值,转为Number来进行运算

//-1 number var a=true; a=-a; console.log(a);

自增

a++与++a自增后,原变量的值会立即自增1.但a++与++a的值不同

a++ //2 1 var a=1; var b=a++; console.log(a); console.log(b); ++a //2 2 var a=1; var b=++a; console.log(a); console.log(b);

自减

a–与--a自减后,原变量的值会立即自增1.但a–与--a的值不同

a– //0 0 var a=1; var b=a--; console.log(a); console.log(b); –a //0 1 var a=1; var b=--a; console.log(a); console.log(b);

逻辑运算符 非与或

非! 对于布尔值: //false var a=true; a=!a; console.log(a); 如果对于非布尔值进行运算,则会将其先转换为布尔值,然后再取反。 //false var a=10; a=!a; console.log(a); 可以利用该特点,将其他数据类型转换为布尔数据类型,此时应取反二次,原理与Boolean()函数一样。 //true var a=1; a=!!a; console.log(a); 与&&:JS中的与属于短路的与。 –布尔值的与运算 //false var a=true; var b=false; console.log(a&&b);

–非布尔值的与运算: 第一个值为true,必然返回第二个值; 第一个值为false,必然返回第一个值;

(1)两者皆为true,返回后面的。

//2 var a=1&&2; console.log(a);

(2)如果两个值中有false,则返回靠前的false.

//NaN var a=NaN&&0; console.log(a); 或||:JS中的或属于短路的或。 第一个值为true,必然返回第一个值; 第一个值为false,直接返回第二个值;

赋值运算符

= 、+=、-=、*=、/=、%=

关系运算符:比较两值大小,关系成立返回true,否则返回false

非数值情况:会将其转换为数字再做比较。 任何值与NaN做比较都是false. 如果符号两侧的值都为字符串,不会将其转换为数字比较,而是分别比较字符串中字符的Unicode编码。 比较字符串时是一位一位的进行比较,如果两位一样,则比较下一位。 可以借其对英文进行排序。 如果比较的是字符串型的数字,可能会得到不可预期的结果。 eg. console.log(“11”<“5”); //falseconsole.log("a"<"b");//true console.log("abc"<"b");//true

相等运算符

值类型不同,会自动类型转换为相同数据类型进行比较。 //true console.log("1"==1); 大多将二者都转为Number。 //true console.log(true=="1"); 特殊: //false console.log(null==0); undefined衍生自null,所以两者做相等判断时,会返回true。 NaN不和任何值相等,包括本身。判断一个值是否为NaN:isNaN()函数 //true var b=NaN; console.log(isNaN(b)); != 不相等——>true ;相等——>false.也会将不同类型转换为同种类型。===全等,判断两个值是否相等。 如果两值类型不同,直接返回false,不会做类型转换 //false console.log(null===undefined);

三元运算符(条件运算符)

条件表达式?语句1:语句2 如果条件表达式为非布尔值,先转为布尔值,再计算 javascript //语句1 "hello"?alert("语句1"):alert("语句2");

运算符的优先级

,分割多个语句。 eg. var a,b,c;先乘除后加减.&&优先级高于||.

流程控制语句

条件判断语句

语法1:if语句只能控制紧随其后的那一条语句。 if(条件表达式){ 语句 } if语句中,代码块并非必须写,但尽量写,即使if后只有一条语句。 (1)水仙花数 代码链接: link. (2)质数 代码链接: link.语法2: if…else…语法3:只有一个代码块会被执行。 if…else if…else… 判断分数: 用prompt输入成绩,score<0或score>100或是NaN或是未输入时,提示用户相应的错误。 100分 电脑 80 平板 60 参考书 其他 棍棒。 代码链接: link. if语句中,代码块并非必须写,但尽量写,即使if后只有一条语句。

条件分支语句 switch

switch(条件表达式){ case表达式: 语句… break; . . . default: 语句… break; }

循环语句

while循环 (1)死循环,不会停止直到浏览器关闭,慎用。当然可以使用 break来终止死循环。 while(true){ 语句; } (2)循环三步骤:初始化变量;在循环中设置条件表达式;定义一个更让新表达式,每次更新初始化变量。var i=0; while(i<0){ alert(i); i++; } do…while循环。循环体至少执行一次。 do{ 语句… }while(条件表达式)for循环 for(){ 语句… } for循环的三个部分可以省略。 (1)死循环 for(;;){ alert("hello"); }

(2)0 1 2 3 4 5 6 7 8 9 javascript var i=0; for(;i<10;){ alert(i++); } 输入比较大小数值进行排序(正向、反向)。 使用方法:(1)冒泡排序法;(2)sort()方法以及reverse()方法。

代码链接: link.

break continue

break关键字可以退出switch或循环语句。不能在if中使用。 break只能终止与其最近的循环。 如果有两层循环,如果想终止外层循环,使用标记来标识。

// An highlighted block var foo = 'bar';<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> outer: for(var i=0;i<5;i++){ alert("外层循环"+i); for(var j=0;j<5;j++){ break outer; alert("内层循环"+j); } } </script> </head> <body> </body> </html>

continue跳过当次循环

测试程序的性能 在程序执行前,开启计时器。console.time();用字符串作为参数 终止计时器console.timeEnd();

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> // 外层循环决定高度,内层循环决定宽度 console.time("time"); for(var i=1;i<=9;i++){ for(var j=1;j<=i;j++){ document.write("<span>"+i+"*"+j+"="+i*j+"</span>"); } document.write("<br/>"); } console.timeEnd("time"); </script> <style> span{ display: inline-block; width: 80px; } </style> </head> </html>

对象(Object)引用数据类型

基本数据类型都是单一的值,值与值之间没有任何的联系,对象子属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。

对象的分类

对象的分类: 1)内建对象。(在ES标准中定义的对象)在任何的ES的实现中都可以使用。eg. Math String Function 2)宿主对象。由JS的运行环境提供的对象,目前来讲主要是值由浏览器提供的对象。eg. BOM、DOM 3) 自建对象。

创建对象

var obj=new Object(); 使用new关键字调用的函数,是构造函数(用以创建对象的函数)。使用typeof检查一个对象时,会返回object.向对象中添加属性(对象中保存的值) 语法: 对象.属性名=属性值 eg. var obj=new Object(); obj.name=“孙悟空”;//向obj中添加一个name属性读取对象的属性 语法: 对象.属性名 console.log(obj.name); 如果读取对象中没有的属性,不会报错而是返回undefined修改对象的属性值 语法: 对象.属性名=新值 obj.name=“Tom”;删除对象的属性 语法:delete 对象.属性名 delete obj.namel

属性名和属性值

属性名:对象的属性名不强制要求遵守标识符的规范,但尽量按照标识符规范去做。 如果要使用特殊的属性名,不能使用.的发送来操作 语法: 对象[“属性名”]=属性值

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> var obj=new Object(); //obj.123=789;会报错 obj[123]=789; console.log(obj[123]); </script> </head> <body> </body> </html> 使用[]形式去操作属性,更加的灵活。 在[]中可以直接传递一个变量,这一变量值为多少就会读取那个属性。 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> var obj=new Object(); obj[123]=789; obj["你好"]="nihao"; var n=123; console.log(obj[n]); </script> </head> <body> </body> </html>

属性值:JS对象的属性值,可以是任意的数据类型,甚至可以是一个对象

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> var obj=new Object(); obj.test=123; alert(obj.test);//123 var obj2=new Object(); obj2.name="猪八戒"; obj.test=obj2; alert(obj.test);//[object Object] alert(obj.test.name);//[猪八戒] </script> </head> <body> </body> </html>

3.对象的属性值也可以是一个函数

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> var obj=new Object(); obj.name="孙悟空"; obj.sayName=function(){//匿名函数 alert(obj.name); }; obj.sayName(); </script> <body> </body> </html>

调用对象的方法

函数成为一个对象的属性保存,则称函数为这个对象的方法。调用函数即为调用对象的方法。

枚举对象中的属性(解决不知对象中有那些属性的问题)

语法:for(var 变量 in 对象){

}

// name age gender 孙悟空,18,男 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> var obj={ name:"孙悟空", age:18, gender:"男" } for(var n in obj){ console.log(n); alert(obj[n]); } </script> <body> </body> </html>

in运算符

in运算符:检查一个对象中是否含有指定的属性。 有返回true 无返回false语法: “属性名” in 对象 alert("test"in obj);//true

栈内存(先进后出)、堆内存(先进先出)

1. 栈内存

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> var a=123; var b=a; a++; console.log("a="+a); console.log("b="+b); </script> </head> <body> </body> </html>

基本数据类型的值都是直接在栈内存中存储,值与值之间独立存在,修改一个变量不会影响其他变量。 2. 堆内存 对象保存在堆内存中,每创建一个新的对象,就会在堆内中开辟一个新的空间。 变量保存的为对象的内存地址(对象的引用)。 如果两个变量保存的是同一个对象引用,一个变,另一个也随之改变。 当比较两个基本数据类型值时,就是比较值。 当比较两个引用数据类型值时,就是比较对象的内存地址。

对象字面量

var obj={};//等同于var obj=new Object(); console.log(typeof obj);//object 优点:使用对象字面量可以在创建对象时,直接指定对象的属性。 语法:{属性名:属性值,属性名,属性值…} var obj2={name:“猪八戒”}; 对象字面量的属性名可以加引号,也可以不加,建议不加,如果使用一些特殊的名字,则必须加引号。 属性名与属性值是一组一组的名值对结构。

函数(Function)

函数也是一个对象,其中可以封装一些功能,在需要时执行。

方法一: (1)创建一个函数对象 var fun=new Function(); 使用typeof检查一个函数对象时,会返回function,可以将要封装的代码以字符串形式传递给构造函数。封装到函数中的代码不会立即执行,除非调用时。 eg. var fun=new Function(“console.log(‘hello’);”); (2)调用函数 函数对象() eg. fun();//此时代码会执行方法二: 使用函数声明来创建一个函数 语法:function 函数名([形参1,形参2,…形参n]){语句…}方法三: 使用函数表达式 赋值语句 var 函数名=function([形参1,形参2,…形参n]){语句…};

函数的参数

在函数的()中指定一个或多个形参(形式参数),声明参数相当于在函数内部声明了相应的变量,未赋值。

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function sum(a,b){ alert(a+b); } sum(1,2); </script> </head> <body> </body> </html>

调用函数时解析器不会检查实参的类型,所以注意有可能会接收到非法的参数,如果有则需检查参数类型。 调用函数时解析器也不会检查非法的参数,,多余的不会被赋值。

函数的返回值

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function sum(a,b,c){ alert(a+b+c); } sum(1,2,3); </script> </head> <body> </body> </html>

使用return来设置函数返回值 语法:return 值; return;相当于return+undefined;不写return也相当于返回undefined。 1.练习一:

// 定义一个函数,判断一个数是否为偶数。 true,false <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function fun(num){ if(num%2==0){ alert("true"); } else{ alert("false"); } } var input=parseInt(prompt("请输入一个数:")); fun(input); </script> </head> <body> </body> </html>

2.练习二: Number.isInteger()用来判断一个值是否为整数。但输入负数时 需要注意的是,在JavaScript内部,整数和浮点数是同样的储存方法,所以3和3.0被视为同一个值。

Number.isInteger(25) // true Number.isInteger(25.0) // true Number.isInteger(25.1) // false Number.isInteger("15") // false Number.isInteger(true) // false

3.练习三:

// 定义一个函数,可以根据半径计算一个圆的面积并返回结果。 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function fun(r){ //正整数 if(r%1==0){ return (Math.PI*r*r).toFixed(2);//结果保留两位小数 } //float else{ r=Math.floor(r*100)/100;//半径保留两位小数 return (Math.PI*r*r).toFixed(2); } } //求圆的面积,所以应为正数 var num=+(prompt("请输入一个正数:")); while(num<0||isNaN(num)==true){ num=+prompt("输入错误,请输入一个正数"); } var result=fun(num); alert("圆的面积为"+result); </script> </head> <body> </body> </html>

4.练习四: 创建一个函数,在控制台输出个人信息。输出结果:我是孙悟空,我今年18岁了,我是男性,我住在花果山 (1)方法一:参数过多容易混乱

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function info(name ,age,gender,address){ console.log("我是"+name+",我今年"+age+"岁了,我是"+gender+"性,我住在"+address); } info("孙悟空",18,"男","花果山"); </script> </head> <body> </body> </html>

实参可以是任意的数据类型,也可以是个对象。参数过多时,可以将其封装至对象中。 (2)方法二:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function info(obj1){ console.log("我是"+obj1.name+",我今年"+obj1.age+"岁了,我是"+obj1.gender+"性,我住在"+obj1.address); } var obj={ name:"孙悟空", age:18, gender:"男", address:"花果山" } info(obj); </script> </head> <body> </body> </html>

此时哪怕对象中信息顺序变换(eg. name:"孙悟空"与age:18先后顺序变换),也不影响值的正确输出。 实参也可以是一个函数。 (1)调用函数对象

// a=function fun(r){ return Math.PI*r*r; } <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function fun(r){ return Math.PI*r*r; } function fun2(a){ console.log("a="+a); } fun2(fun); </script> </head> <body> </body> </html>

(2)调用函数

// a=12.57 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function fun(r){ return Math.PI*r*r; } function fun2(a){ console.log("a="+a); } fun2(fun(2).toFixed(2)); </script> </head> <body> </body> </html>

返回值的类型(任意)

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function login(){ var id=prompt("请输入账号:"); var psw=prompt("请输入密码:"); for(var i=0;i<3;i++){ if(id=="123"&&psw=="456"){ alert("登录成功!"); return;//结束整个函数 } id=prompt("请重新输入正确格式的账号"); psw=prompt("请重新输入正确格式的密码"); } alert("账号锁定"); } login(); </script> </head> <body> </body> </html> // 我是fun1 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function fun(){ function fun1(){ alert("我是fun1"); } fun1(); } fun(); </script> </head> <body> </body> </html>

立即执行函数

函数定义完立即被执行,只会执行一次。

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> (function(){ alert("我是一个匿名函数~"); })();//如何不加会报错,调用函数(); </script> <body> </body> </html>

全局作用域(scope)

作用域:变量的作用范围 在JS中有两种作用域:(1)全局作用域;(2)函数作用域

1.全局作用域

在页面打开时创建,页面关闭时销毁。在全局作用域中有一个全局对象(window),代表浏览器创建。 console.log(window);//[object window]

–在全局作用域中创建的变量都会作为window对象的属性保存。

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> var a=10; console.log(window.a);//10 </script> <body> </body> </html>

–在全局作用域中函数都会作为window对象的方法保存。

变量、函数的声明提前

// a=123等于window.a=123 a=123; console.log(a);//123

(1)使用var关键字声明的变量,会在所有代码执行之前被声明。不使用var关键字,则不会被声明提前。 (2)函数的声明提前:使用函数声明形式创建的function函数会在所有代码执行之前被创建。

// fun1 fun(); function fun(){ console.log("fun1"); }

使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用。

// 报错,fun2()为方法,而fun2为变量 fun2(); var fun2=function(){ console.log("fun2"); }

2.函数作用域

1.调用时创建函数作用域,函数执行完毕以后,销毁。每调用一次,便会创建一个新的函数作用域,他们之间相互独立。 2.在函数作用域中可以访问到全局作用域中的变量; 在全局作用域中不可以访问到函数作用域中的变量。 3. 当在函数作用域中操作一个变量时,它会在自身作用域中寻找,如果有就直接使用,如果没有就向上一级作用域中寻找。直到找到全局作用域,如果全局作用域中也没有,则会报错。

var a=10; function fun(){ var a="hello"; console.log("a="+a); } fun();//hello var a=10; function fun(){ var a="hello"; } fun(); console.log("a="+a);//10 在函数中访问全局变量a,使用window.a即可。在函数作用域中,也有声明提前的特性。函数声明也会在函数中所有代码执行之前执行。在函数中,不使用var声明的量都会变为全局变量。 var a=33; function fun(){ a=10; } fun(); console.log("a="+a);//10

8.定义形参相当于在函数作用域中声明了变量

var a=33; function fun(a){ alert(a); } fun();//undefined

函数的方法

call()和apply()这两个方法都是函数对象的方法,需要通过函数对象来调用,当对函数调用call()和apply()都会调用函数执行。在调用call()和apply()可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时的this。function fun(){ alert(this.name); } var obj={name:"猪八戒"}; var obj2={name:"孙悟空"}; fun.apply(obj); call()方法可以实现将实参在对象之后依次传递。 apply()方法需要将实参封装在一个数组中统一传递。 两者都可以改变this指向。

this(上下文对象)

1.解析器在调用函数每次都会向函数内部传递一个隐含的参数,这个隐藏的参数就是this。this指向的是一个对象,称之为函数执行的上下文对象。 根据函数的调用方式不同,this会指向不同的对象。

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> function fun(){ console.log(this); } var obj={ name:"孙悟空", sayName:fun } obj.sayName(); fun(); //以上等同,不过前者为object object 后者为object window </script> <body> </body> </html>

以函数的形式调用时,this永远就是window。 以方法的形式调用时,this就是调用方法的对象。 以构造函数形式调用时,this就是新创建的那个对象。 用call和apply调用时,this就是指定的那个对象。

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> function fun() { console.log(this.name);//调用哪个输出那个,更为方便 } var obj = { name: "孙悟空", age: 18, sayName: fun } var obj2 = { name: "猪八戒", age: 16, sayName: fun } obj.sayName(); obj2.sayName(); </script> <body> </body> </html>

arguments实参

在调用函数时,浏览器每次会传递两个隐含的参数。 (1)函数的上下文对象this (2)封装实参的对象arguments(并非数组)。而是类数组对象,可以通过索引来操作数据,也可以获取长度。 在函数调用时,所传递的实参都会封装到arguments中。function fun(){ console.log(arguments[1]);// true } fun("hello",true); 即使不定义形参,也可以通过arguments来使用实参(稍微麻烦) arguments[0] 表示第一个实参属性:callee(这个属性对应一个函数对象,即当前正在指向的函数的对象)

工厂方法创建对象

使用工厂方法创建对象,使用的构造函数都是Object.

//猪八戒 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> function createPerson(name,age,gender){ var obj=new Object(); obj.name=name; obj.age=age; obj.gender=gender; obj.sayName=function(){ alert(this.name); }; return obj; } var obj2=createPerson("猪八戒",18,"男"); var obj3=createPerson("白骨精",18,"女"); obj2.sayName(); </script> <body> </body> </html>

构造函数

首字母大写,调用方式不同,构造函数需要new关键字来调用。 1.执行流程: (1)立即创建一个新的对象 (2)将新建对象设置为函数中this,在构造函数中可以使用this来引用新建的对象。 (3)执行函数中的代码 (4)将新建函数作为返回值返回。

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> function Person(name,age,gender){ this.name=name; this.age=age; this.gender=gender; this.sayName=function(){ alert(this.name); }; } var per2=new Person("孙悟空",18,"男"); console.log(per2); </script> <body> </body> </html>

2. 将通过一个构造函数创建的对象称之为该类的实例。 使用instanceof可以检查一个对象是否为一个类的实例 语法: 对象 instanceof 构造函数 eg. console.log(per2 instanceof Person);//true 所有的对象都是object的后代。任何对象和object做instanceof检查时都会返回true> 3.this的情况

调用方式this函数window方法谁调用this就是谁构造函数新创建的对象

构造函数修改

1.👍

// 大家好,我是孙悟空 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> function Person(name,age,gender){ this.name=name; this.age=age; this.gender=gender; this.sayName=function(){ alert("大家好,我是"+this.name); }; } var per2=new Person("孙悟空",18,"男"); per2.sayName(); </script> <body> </body> </html>

在构造函数中,为每一个对象都添加了一个sayName 1中的方法是在构造函数内部创建的,也就是构造函数每执行一次就会创建一个新的sayName方法,这样导致如果该构造函数执行1000次,便会创建1000个一模一样的新的方法。 2.👍👍

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> function Person(name,age,gender){ this.name=name; this.age=age; this.gender=gender; this.sayName=fun; } function fun(){ alert("大家好,我是"+this.name); }; var per2=new Person("孙悟空",18,"男"); per2.sayName(); </script> <body> </body> </html>

但将函数定义在全局作用域,污染了全局作用域的命名空间,也很不安全。

原型(prototype)

1.所创建的每一个函数,解析器都会向函数中添加一个属性prototype,这个属性对应着一个对象,即所谓的原型对象。 2.如何函数作为普通函数调用prototype时,没有任何作用。以构造函数形式调用时,它所创建的对象都会有一个隐含的属性,指向该构造函数的原型对象,通过_proto_访问该对象。 3. 原型对象就相当于一个公共的区域,所有的同一个类的实例都可以访问到这个原型对象。(可以将对象中共有的内容,统一设置到原型对象中)

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> function MyClass(){ } var mc=new MyClass(); MyClass.prototype.sayHello=function(){ alert("hello"); } console.log(mc.__proto__); console.log(MyClass.prototype); </script> <body> </body> </html>

mc._proto_与MyClass.prototype一样。 向MyClass的原型中添加属性a

MyClass.prototype.a=123; console.log(mc.a); mc.sayHello();

123 hello 当访问对象的属性或方法时,其会在对象自身中寻找,有则使用,无去原型对象中寻找。 👍👍👍

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> function Person(name ,age,gender){ this.name=name; this.age=age; this.gender=gender; } Person.prototype.sayName=function fun(){ alert("大家好,我是"+this.name); }; var ps=new Person("猪八戒",18,"男"); ps.sayName(); </script> <body> </body> </html>

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

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> function MyClass(){ } MyClass.prototype.name="hello"; var mc=new MyClass(); console.log(mc.name);//hello console.log("name" in mc);//true console.log(mc.hasOwnProperty("name"));//flase </script> <body> </body> </html>

in检查对象是否含有某个属性时,如果对象中没有,但原型中有,也会返回true。 使用hasOwnProperty()来检查自身中是否含有该属性。 原型对象也是对象,所有它也有原型。

toString方法

在页面打印一个对象时,实际上输出的为对象的toString()方法的返回值。 当不希望在输出对象时输出[object Object],可以为对象添加一个toString()方法。

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function Person(name,age,gender){ this.name=name; this.age=age; this.gender=gender; } //创建一个per实例 var per=new Person("孙悟空",18,"男"); var per2=new Person("猪八戒",18,"男"); Person.prototype.toString=function(){ return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]"; } //只对per起作用,要想全部起作用,得对原型 // per.toString=function(){ // return "Psrson[name="+this.name+",age="+this.age+",gender="+this.gender+"]"; // } console.log(per);//object var result=per2.toString(); console.log(result);//string </object> </script> </head> </html>

垃圾回收(GC)

垃圾:当一个对象没有任何的变量或属性对其引用,此时将无法操作该对象,过多时占用大量内存空间。JS拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁(我们不需要也不能进行垃圾回收操作),我们只需将不再使用的对象设置为null即可。

数组(对象)——>存储性能好

数组(Array):存储数据,普通对象使用字符串作为属性名,而数组使用数字作为索引操作元素。

数组的操作

创建数组对象。

var arr=new Array(); console.log(typeof arr);//object //也可以同时添加元素 var arr1=new Array(1,2,3); console.log(arr1);//Array(3) [ 1, 2, 3 ]

向数组中添加元素 语法:数组[索引]=值

读取元素 语法: 数组[索引] 如果读取不存在的数组,不会报错,返回undefined

获取数组长度(元素的个数) 语法:数组.length (连续的数组)

var arr=[]; arr[0]=1; arr[1]=2; arr[2]=12; console.log(arr.length);//3

对于非连续的数组,使用length会获取到数组的最大索引+1。

var arr=[]; arr[0]=1; arr[1]=2; arr[2]=12; arr[10]=13; console.log(arr.length);//11

修改数组length。

向数组的最后一位添加元素。 数组[数组.length]=值

var arr=[]; arr[0]=1; arr[1]=2; arr[2]=12; arr[arr.length]=30; console.log(arr);//Array(4) [ 1, 2, 12, 30 ]

数组字面量

var arr=[],等同于var arr=new Array();在创建时指定数组元素。var arr=[1,2,4]; console.log(arr);//Array(3) [ 1, 2, 4 ] console.log(arr.length);//3 创建一个数组里面只有一个元素10var arr=[10]; console.log(arr); console.log(arr.length); 创建一个数组,长度为10var arr=new Array(10); console.log(arr);// ,,,,,,,,,, 在数组中的元素可以为任意类型的数据类型,也可以为对象。也可以是一个函数还可以放数组var arr=["hell0",1,null,true,undefined]; var arr1=[{name:"孙悟空"},{name:"猪八戒"}]; var arr2=[function(){alert(1)},function(){alert(2)}]; var arr3=[[1,2,3],[2,3,4],[3,4,5]]; console.log(arr); console.log(arr1[1].name); console.log(arr2[0]); console.log(arr3[0]);

数组的方法

push()方法:向数组末尾添加一个或多个元素,并返回数组新的长度。

var arr=["孙悟空","猪八戒","沙和尚"]; var s=arr.push("唐僧"); console.log(s); console.log(arr);

pop()方法:删除数组的最后一个元素,并将被删除元素返回。

var arr=["孙悟空","猪八戒","沙和尚"]; var s=arr.push("唐僧"); console.log(arr); var t=arr.pop(); console.log(arr); console.log(t);

unshift()方法:向数组开头添加一个或多个元素,并返回新的数组长度。

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

shift()方法:删除并返回数组的第一个元素。

var arr=[1,2,3,4,5,6]; var result=arr.shift(); console.log(arr);//Array(5) [ 2, 3, 4, 5, 6 ] console.log(result);//1

slice(start,[end])

从数组中提取指定元素。 参数:截取开始的位置索引(包含开始索引);截取结束位置的索引(不包含结束索引),可省略不写。 该方法不会改变数组元素,而是将截取到的元素封装在一个新数组返回。

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

splice()删除数组的指定元素

splice()方法:删除数组的指定元素。会影响到原数组,并将删除的元素作为返回值返回。 参数:表示开始位置的索引;表示删除的数量;第三个及以后,可以传递新的元素,这些元素会自动插入到开始位置索引前边。

var arr=[1,2,3,4,5]; var s=arr.splice(1,3); console.log(arr);// Array [ 1, 5 ] console.log(s);//Array(3) [ 2, 3, 4 ] var arr=[1,2,3,4,5]; var result=arr.splice(0,1,6,7,8); console.log(arr);//Array(7) [ 6, 7, 8, 2, 3, 4, 5 ] console.log(result);//Array[1]

conact()

conact()该方法不会对原数组产生影响。 可以连接两个或多个数组,并将新的数组返回,还可以传字符串。

var arr = [1, 2, 3]; var arr1 = [4, 5, 6]; var s = arr.concat(arr1); console.log(s);//Array(6) [ 1, 2, 3, 4, 5, 6 ]

join([splitor])

该方法可以将数组转为一个字符串。(不会对原数组产生影响,而是将转换后的字符串作为结果返回)

var arr=[1,2,4]; var s=arr.join(); console.log(typeof s);//string console.log(s);// 1 2 4

在join()中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符(默认为,)

var arr=["猪八戒","孙悟空","沙和尚"]; var result=arr.join("-"); console.log(result);//猪八戒-孙悟空-沙和尚

reverse()

反转数组该方法会直接修改原数组。

var arr=["猪八戒","孙悟空","沙和尚"]; arr.reverse(); console.log(arr);//Array(3) [ "沙和尚", "孙悟空", "猪八戒" ]

sort()

对数组元素进行排序(会影响原数组,默认会按照Unicode编码进行排序)

var arr=["b","c","e","a","f"]; arr.sort(); console.log(arr);//Array(5) [ "a", "b", "c", "e", "f" ] var arr=[11,2,5,6,7,3]; arr.sort(); console.log(arr);//Array(6) [ 11, 2, 3, 5, 6, 7 ]

即使对于传数字的数组,使用sort()排序时,也会按照Unicode编码来排序,所以对数组进行排序时,可能会得到错误的结果。 解决方案:自己指定排序的规则,在sort()添加一个回调函数来指定排序规则。 (1)回调函数中调用两个形参,浏览器会分别使用数组中的元素作为实参去调用回调函数。 (2)使用那个元素调用不确定,但肯定的时在数组中a一定在b前边。 (3)浏览器会根据回调函数的返回值来决定元素的顺序。

var arr=[11,2,5,6,7,3]; arr.sort(function(a,b){ return a-b; }); console.log(arr);//Array(6) [ 2, 3, 5, 6, 7, 11 ]

遍历数组forEach

forEach()方法只支持IE8以上的浏览器。forEach()方法需要一个函数作为参数,此时如果在全局作用域中创建函数,污染了全局作用域的命名空间,也不安全,需用匿名函数(自调用)。数组中有几个元素函数就会执行几次,浏览器将会遍历到的元素以实参的形式传递进来,定义形参读取内容。浏览器会在回调函数中传递三个参数(value,index,正在遍历的数组obj)var arr=[1,2,3,4,5]; arr.forEach(function(value,index,obj){ console.log("value="+value);// 1 2 3 4 5 }) 解决不支持IE8及以下不兼容问题。链接: link.

常用类和方法

包装类

在JS中提供了三个包装类,通过这三个包装类可以将基本数据类型的数据转换为对象。 (1)String():将基本数据类型字符串转换为String对象。 (2)Number():将基本数据类型的数字转换为Number对象。 (3)Boolean():将基本数据类型的布尔值转换为Boolean对象。

实例

//地址不同,但Boolean可以 var num=new Number(3); console.log(typeof num);//object var num1=new Number(3); console.log(num==num1);//false

在实际应用中基本不会使用基本数据类型的对象。因为如果使用基本数据类型的对象,在做一些比较时可能会带来一些不可预期的结果。

var bool=new Boolean(true); var bool2=true; console.log(bool==bool2);//true console.log(bool===bool2);//false ===恒等操作符(数值、地址相同)

方法和属性只能添加给对象。不能添加给基本数据类型。

当我们去操作一个基本数据类型的属性和方法时, 解析器会临时将其转换为对应的包装类,然后再去操作属性和方法, 操作完成以后再将这个临时对象进行销毁。

Date

创建一个Date对象var d=new Date(); console.log(d);//Date Wed Nov 04 2020 21:39:19 GMT+0800 (中国标准时间) 创建一个指定的时间对象 需要在构造函数中传递一个表示时间的字符串作为参数。var d=new Date("11/04/2020"); console.log(d);//Date Wed Nov 04 2020 00:00:00 GMT+0800 (中国标准时间) 时间格式:月份/日/年 时:分:秒getDate():获取当前日期对象是几日var d=new Date("11/04/2020"); var date=d.getDate(); console.log(date);//4 getDay():获取当前日期的对象为周几,返回0-6(0即为周日)getMonth():返回0-11getFullYear()getTime():获取当前日期对象的时间戳。 时间戳:从格林威治标准时间的1970年1月1日0时0分0秒到当前日期所花费的毫秒数。 计算机底层保存时间时使用的都是时间戳。获取当前时间的时间戳var d=Date.now(); console.log(d);//1604497771097 (1)利用时间戳来测试代码的执行性能var start=Date.now(); // 查看for循环代码执行时间 for(var i=0;i<100;i++){ console.log(i); } var end=Date.now(); console.log(end-start);//7

Math

Math:和其他的构造对象不同,他不是一个构造函数,它属于工具类,不用创建对象,其内封装了数学运算相关的属性和方法。

方法功能Math.ceil向上取整Math.floor向下取整Math.round四舍五入取整Math.random生成0-1之间的随机数Math.max获取多个数的最大值Math.pow(x,y)返回x的y次幂Math.sqrt()开方

0-x的随机数 Math.round(Math.random()x) x-y的随机数 Math.round(Math.random()(y-x)+x)

字符串的相关的方法

在底层字符串都是以字符数组的形式保存的。 var str="hello"; console.log(str.length);//5 console.log(str[0]);//h length属性:获取字符串的长度。(不用加())。charAt():返回字符串中指定位置的字符。var str="hello"; console.log(str[0]);//h var s=str.charAt(0); console.log(s);//h charCodeAt():获取指定位置字符的字符编码(Unicode编码十六进制) var str="hello"; var s=str.charCodeAt(0); console.log(s);//104 fromCharCode():根据字符编码获取字符。var s=String.fromCharCode(104); console.log(s);//h concat():作用与±一样。 var str="hello"; var result=str.concat("你好","bye"); console.log(result);//hello你好bye indexof():该方法可以检索一个字符串中是否有指定内容。有返回索引,无返回-1。 可以指定一个第二个参数,指定开始查找的位置。 var str="hello"; var result=str.indexOf("h"); console.log(result);//0 result=str.indexOf("1",3); console.log(result);//-1 lastIndexOf():从后往前找,也可以指定开始查找的位置。var str="hello"; var result=str.lastIndexOf("0"); console.log(result);//-1 slice():从字符串中截取指定的内容,不会影响原字符串。 参数:开始位置的索引(包括);结束位置的索引(不包括) 如果第二个参数被省略,则会截取到后面所有的。 var str="hello"; var result=str.slice(0,2); var s=str.slice(1); console.log(result);//he console.log(s);//ello substring():用以截取一个字符串,与slice类似。 参数:开始位置的索引(包括);结束位置的索引(不包括) 如但这个方法不能接受负值为参数,如果传递了参数,则默认使用0,而且会自动调整参数的位置,如果第二个参数小于第一个参数,则自动交换。(反对使用,ES未定义,但大部分浏览器支持。) var str="hello"; var result=str.substring(1,3); console.log(result);//el substr():用以截取字符串 参数:截取开始位置的索引;截取的长度。 var str="hello"; var result=str.substr(1,3); console.log(result);//ell split():将字符串拆分为一个数组。 参数:用字符串作为参数用以拆分数组。 var str="hello,ck,xhn"; var result=str.split(","); console.log(result);// ["hello", "ck", "xhn"] console.log(Array.isArray(result));//true console.log(result[0]);//hello toUpperCase():转大写,不影响原字符串。 var str="hello"; var s=str.toUpperCase(); console.log(s);//HELLO toLowerCase():转小写

正则表达式

定义一些字符串的规则。 计算机可以根据正则表达式来检查一个字符串是否符合规则或者将字符串中符合规则的内容提取出来。

创建正则表达式 var 变量=new RegExp(“正则表达式”,“匹配模式”); 正则表达式:object; 匹配模式:i:忽略大小写;g:全局匹配模式

正则表达式的方法。 test():检查一个字符串是否符合正则表达式规则。(true,false)

var reg=new RegExp("a"); var str="hello a"; var s=reg.test(str); console.log(s);//true

语法

使用字面量来创建正则表达式 语法: var 变量=/正则表达式/匹配模式 (1)检查一个字符串中是否含有a或b(忽略大小写)

var reg=/a|b/i; console.log(reg.test("a"));//true

(2)创建一个正则表达式来检查一个字符串中是否含有字母。 [A-z]任意字母

var reg=/[a-z]/;//任意小写字母 console.log(reg.test("a"));//true

(3) 检查一个字符串中是否含有abc或adc或aec

var reg=/a[bde]c/; console.log(reg.test("aec"));//true

(4) 检查一个字符串中不含ab

var reg=/^[ab]/; console.log(reg.test("abcd"));//true

量词:设置一个内容出现的次数。{n}正好出现n次

// a出现三次 var reg=/a{3}/; console.log(reg.test("aaabac"));//true //ab出现三次 var reg1=/(ab){3}/; console.log(reg1.test("abababac"));//true //b出现1-3次 var reg2=/b{1,3}/g; console.log(reg2.test("abbc"));//true var reg3=/ab+c/; console.log(reg3.test("abcs"));//true

{m,n}出现n次; {m,}:m次以上; +:至少一次,相当于{1,}; *:0个或多个,相当于{0,}; ?:0个或1个,相当于{0,}; ^表示开头,$表示结尾。 检查一个字符串是否以a开头;是否是手机号;是否含有任意字符链接: link. \w:任意字母、数字、下划线; \W:除了字母、数字、下划线; \d:任意的数字; \D:除了数字; \s:空格; \b:单词边界;

字符串和正则相关的方法

根据任意字母来将字符串拆分var str="1a2b3c4d5e6f7g8h9"; var s=str.split(/[A-z]/); console.log(s);//["1", "2", "3", "4", "5", "6", "7", "8", "9"] search():可以搜索字符串中是否含有指定内容只会查找第一个,即使设置全局匹配也没用。有的话返回第一次出现的索引,没有返回-1. var str="hello abc ck abc"; console.log(str.search("abc"));//6 它可以接受一个正则表达式作为参数,然后根据正则表达式去检索。 var str="hello ck abc aec afc abc"; // 检索str中是否含有abc aec 或afc console.log(str.search(/a[bef]c/));//9 match():根据正则表达式,从一个字符串中将符合条件的内容提取出来。 var str="1a2b3c4d5e6f"; console.log(str.match(/[A-z]/));//["a", index: 1, input: "1a2b3c4d5e6f", groups: undefined] console.log(str.match(/[A-z]/g));//["a", "b", "c", "d", "e", "f"] 默认情况下,match()只会找到第一个符合要求的内容,之后停止检索。 解决方法:设置正则表达式为全局匹配模式,这样就会匹配到所有的内容。 var str="1a2b3c4d5e6f7A8B9C"; var s=str.match(/[a-z]/gi); console.log(s); 可以为一个正则表达式设置多个匹配模式,且顺序无所谓。 match()会将匹配到的内容封装到一个数组中返回即使只查询到一个结果。replace():将字符串中指定内容替换为新的内容。 参数:被替换掉内容;新的内容。 可以接收一个正则表达式作为参数,默认值会替换第一个。 var str="1a2b3c4d5e6f7A8B9C"; var s=str.replace(/[a-z]/gi,"🤦"); console.log(s);//1🤦2🤦3🤦4🤦5🤦6🤦7🤦8🤦9🤦

DOM(Document Object Model)

DOM操作

DOM:文档对象模型。JS通过DOM对HTML文档进行操作。 (1)文档:表示整个的HTML网页文档。 (2)对象:表示将网页中的每一个部分都转换为一个对象。 (3)模型:表示对象之间的关系,方便获取对象。

节点(Node) (1)构成网页的最基本的组成部分,网页的每一个部分都可以称为是一个节点。

(2)节点的属性

节点nodeNamenodeTypenodeValue文档节点#document9null元素节点标签名1null属性节点属性名2属性值文本节点#text3文本内容

浏览器已经提供了文档节点对象,这个对象是window属性,可以在页面中直接使用,文档节点代表的是整个网页。

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <script type="text/javascript"> window.onload=function(){ var btn=document.getElementById("btn"); btn.innerHTML="I'm Button"; } </script> <body> <button type="button" id="btn">我是一个按钮</button> </body> </html>

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> *{ padding: 0; margin: 0; } #left{ float: left; width: 25%; border: 1px solid black; margin: 10px 0px 0px 200px; padding: 10px; } #left ul{ display: inline-block; list-style: none; } li{ float: left; padding: 5px; background-color: #6495ED; margin: 5px; } #right{ float: left; width: 25%; margin: 10px; } .button{ width:300px; text-align: center; margin: 5px; } </style> <script type="text/javascript"> window.onload=function(){ // 创建一个“广州”节点,添加到#city下 myClick("btn01",function(){ //创建li元素节点 // 用于创建一个元素节点对象 // 它需要一个标签名作为参数,将会根据标签名创建元素节点对象 // 并将创建好的对象作为返回值返回 var li=document.createElement("li"); //创建li文本节点 // 用来创建文本节点对象 // 需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新的节点返回 var gztext=document.createTextNode("广州"); //将gztext设置为li的子节点 // appendChild():向一个父节点中添加一个新的子节点 //语法: 父节点.appendChild(子节点) li.appendChild(gztext); //获取id为city的节点 var city=document.getElementById("city"); //广州添加到city中 city.appendChild(li); }); //将“广州”节点插入到#bj前面 myClick("btn02",function(){ //创建一个广州 var li=document.createElement("li"); var gztext=document.createTextNode("广州"); //将gztext设置为li的子节点 li.appendChild(gztext); //获取id为bj的节点 var bj=document.getElementById("bj"); //获取city var city=document.getElementById("city"); //insertBefore在指定的子节点前面放入新的节点,用父节点调用 //父节点.insertBefore(新节点,旧节点); city.insertBefore(li,bj); }); //使用“广州”节点替换#bj节点 myClick("btn03",function(){ //新建广州节点 <li>广州</li> var li=document.createElement("li"); var gz=document.createTextNode("广州"); li.appendChild(gz); //获取id为bj的节点 var bj=document.getElementById("bj"); //获取city,通过父节点进行替换 var city=document.getElementById("city"); //使用指定的子节点替换已有的子节点 city.replaceChild(li,bj); }); //删除北京节点 myClick("btn04",function(){ //获取id为bj节点 var bj=document.getElementById("bj"); //获取父节点city // var city=document.getElementById("city"); // //removeChild()删除一个子节点 // //父节点.removeChild(子节点); // city.removeChild(bj); //未知bj的父节点是谁 常用 //子节点.parentNode.removeChild(子节点); bj.parentNode.removeChild(bj); }); //读取#city内的HTML代码 myClick("btn05",function(){ //读取city var city=document.getElementById("city"); alert(city.innerHTML); }); //设置#bj内的HTML代码 myClick("btn06",function(){ //读取bj var bj=document.getElementById("bj"); bj.innerHTML="昌平"; }); //创建一个“广州”节点,添加到#city下 myClick("btn07",function(){ //相当于全删除重新添加的,如果那个列表里绑定了事件,则动作太大 //获取city var city=document.getElementById("city"); // city.innerHTML+="<li>广州</li>"; //结合使用 var li =document.createElement("li"); li.innerHTML="广州"; city.appendChild(li); }); } function myClick(idStr,fun){ var btn=document.getElementById(idStr); btn.onclick=fun; } </script> </head> <body> <div id="left"> <p>你喜欢哪个城市?</p> <ul id="city"> <li id="bj">北京</li> <li>上海</li> <li>东京</li> <li>首尔</li> </ul> </div> <div id="right"> <button class="button" id="btn01">创建一个“广州”节点,添加到#city下</button> <button class="button" id="btn02">将“广州”节点插入到#bj前面</button> <button class="button" id="btn03">使用“广州”节点替换#bj节点</button> <button class="button" id="btn04">删除#bj节点</button> <button class="button" id="btn05">读取#city内的HTML代码</button> <button class="button" id="btn06">设置#bj内的HTML代码</button> <button class="button" id="btn07">创建一个“广州”节点,添加到#city下</button> </div> </body> </html>

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> #top { width:410px; margin: 50px auto; } table { border-collapse: collapse; } table,td,th { border: 1px solid black; padding: 0 17px; } #bottom { width: 410px; border: 1px solid black; margin: 50px auto; } .input{ width: 200px; padding: 5px; margin: 2px; } </style> <script type="text/javascript"> // 为Delete绑定单击响应函数 function delA() { //点击超链接后,删除超链接所在的哪一行 //响应函数里的this,绑定的谁就是谁 //获取当前tr var tr = this.parentNode.parentNode; //获取姓名 //var name=tr.firstChild;//此时需要tr 与td之间无空隙 var name = tr.getElementsByTagName("td")[0].innerHTML; //删除之前弹出提示框 // 用于弹出一个带有确认和取消按钮的提示框,需要一个字符串作为参数,该字符串将会作为提示符显示出来 //如果用户点击确认返回true,取消返回false var result = confirm("确认要删除" + name + "吗?"); if (true) { tr.parentNode.removeChild(tr); } //点击超链接后,超链接会跳转页面,这是超链接的默认行为 //取消该默认行为,通过在响应函数的最后return false来取消默认行为,或者在a中将href设为:javascript:; return false; } window.onload = function() { //点击超链接后,删除一个员工的信息 //获取所有超链接 var allA = document.getElementsByTagName("a"); //为每一个a绑定单击响应函数 //for循环会在页面加载完成后立即执行,而响应函数会在超链接被点击时才执行 //当响应函数执行时,for循环早已执行完毕 for (var i = 0; i < allA.length; i++) { //alert("for循环执行"+i+"次"); allA[i].onclick = delA; } //添加员工信息 //单击submit后响应事件 var btn = document.getElementById("btn"); btn.onclick = function() { //定义变量将用户输入的值保存 var name = document.getElementById("name").value; var email = document.getElementById("email").value; var salary = document.getElementById("salary").value; //新建tr var tr=document.createElement("tr"); //设置tr中的内容 tr.innerHTML="<td>"+name+"</td>"+ "<td>"+email+"</td>"+ "<td>"+salary+"</td>"+ "<td><a href='javascript:;'>Delete</a></td>"; //获取刚刚添加的a元素,并将其绑定单击响应函数 var a=tr.getElementsByTagName("a")[0]; a.onclick=delA; //获取table var table=document.getElementById("table"); //出现问题,新增的信息位于tbody的外面,新增的与原来的不是兄弟节点。 //获取table中的tbody var tbody=table.getElementsByTagName("tbody")[0]; tbody.appendChild(tr); }; } </script> </head> <body> <div id="top"> <table id="table"> <tr> <th>Name</th> <th>Email</th> <th>Salary</th> <th>&nbsp;</th> </tr> <tr> <td>Tom</td> <td>tom@tom.com</td> <td>5000</td> <td><a href="javascript:;">Delete</a></td> </tr> <tr> <td>Jerry</td> <td>jerry@sohu.com</td> <td>8000</td> <td><a href="deleteEmp?id=001">Delete</a></td> </tr> <tr> <td>Bob</td> <td>bob@tom.com</td> <td>10000</td> <td><a href="deleteEmp?id=001">Delete</a></td> </tr> </table> </div> <div id="bottom"> <div style="margin: 5px;text-align: center;" id="info"> <p style="text-align: left;font-size: 18px;font-weight: 500;">添加新员工</p> name: <input class="input" id="name" /></br> email: <input class="input" id="email" /></br> salary: <input class="input" id="salary" /></br> <button class="button" id="btn">Submit</button> </div> </div> </body> </html>

事件(Event)

文档或浏览器窗口发生的一些特定的交互瞬间。JS与HTML之间的交互是通过事件实现的。可以在事件对应的属性中设置一些JS代码,当这些事件被触发时,这些代码将会执行。 var btn=document.getElementById("btn"); btn.onclick=function(){ alert("你还点~~"); } }

文档的加载

将script标签放在body标签后面的原因。 浏览器在加载页面时,按照自上而下的顺序执行的,读取一行执行一行,如果将script标签写在页面的上边,在代码执行之前,页面还没有加载。也可以将script标签放于head标签中,但要正确执行JS代码,应在文档加载完毕后执行script标签中的内容。 设置:文档加载事件 onload事件——>绑定给windows。 追求性能的话写在body标签后。

DOM 查询

获取元素节点 (1)getElementById():通过Id属性获取一个元素节点对象。 (2)getElementByTagName():通过标签名获取一个元素节点对象。 (3)getElementByName():通过name属性获取一个元素节点对象。获取元素节点的子节点 (1)getElementByTagName():方法。返回当前节点的指定标签名后的节点。 (2)childNodes:属性。表示当前节点的所有子节点。 (3)firstChild lastChild:属性。会获取包括文本节点在内的所有节点(空白也算)。但在IE8及以下的浏览器不会将空白文本当作子节点。 (4)children:属性。表示当前节点的所有子元素。 (5)firstElementChild:属性。第一个子元素。(IE9及以上)

document对象的其他的属性和方法

获取父节点与兄弟节点(通过具体的节点调用) (1)parentNode:表示当前节点的父节点。 (2)previousSibling:表示当前节点的前一个兄弟节点。 (3)nextSibling:表示当前节点的后一个兄弟节点。

(1)获取body标签。

window.onload=function(){ var body=document.body; console.log(body); }

(2)html根标签。 (3)页面中的所有元素

var all=document.all; for(var i=0;i<all.length;i++){ console.log(all[i]); }

或者

var all=document.getElementsByTagName("*"); console.log(all.length);

(4)根据元素的class属性值查询一组元素节点对象。

window.onload=function(){ var btn=document.getElementsByClassName("btn"); console.log(btn.length); }

(5)document.querySelector() 包括(IE 8及以上) 需要用一个选择器的字符串作为参数,可以根据一个CSS选择器来查询一个节点对象。

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <script type="text/javascript"> window.onload=function(){ var div=document.querySelector(".box1 div"); console.log(div.innerHTML);//hello } </script> </head> <body> <button type="button" class="btn">我是一个按钮</button> <div class="box1"> <div > hello </div> </div> </body> </html>

使用该方法只会返回唯一的一个元素,如果满足条件的元素有多个,那么它只返回第一个。 (5) document.querySelectorAll():方法与4一样用法类似,不同的是它会将符合条件的元素封装到一个数组中返回。即使符合条件的元素只有一个,他也会返回数组。

DOM增删改

创建li元素节点。 var li=document.createElement(“li”);

创建“广州”文本节点。 var gz=document.createTextNode(“广州”);

appendChild():向父节点中添加一个新的节点。 父节点.appendChild(新节点);

insertBefore():在指定的子节点前面放入新的节点,用父节点调用。 父节点.insertBefore(新节点,旧节点);

replaceChild():用指定的子节点替换已有的子节点。父节点.replaceChild(新节点,旧节点);

removeChild():删除一个子节点。 父节点.removeChild(子节点); 未知父节点:子节点.parentNode.removeChild(子节点);

获取节点的HTML代码:alert(节点.innerHTML);

设置节点的HTML代码:节点.innerHTML=“昌平”;

创建一个广州节点,添加至#city下。

具体代码 链接: link.

DOM对CSS的操作

通过JS修改元素的样式 元素.style.样式名=样式值 eg. box1.style.width=“200px”; 如果样式表中含有-,这种名称在JS 中是不合法的——>将这种样式名修改为驼峰命名法,去掉-,然后将-后的字母大写。 比如:background-color——>backgroundColor 🐖:通过style属性设置的样式都是内联样式,而内联样式具有较高的优先级,所以通过JS修改的样式往往会立即显示 。 🐖:尽量不要为样式添加!important 如果写了!important,样式会具有最高级的优先级(即使通过JS代码也不能覆盖该样式)——>JS修改样式失效读取元素样式 元素.style.样式名 通过style属性设置和读取的都是内联样式,无法读取到样式表的样式。

获取元素当前的样式

定义函数 用于获取指定元素的当前的样式<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> #btn{ background-color: blue; } </style> <script type="text/javascript"> window.onload=function(){ var btn=document.getElementById("btn"); //参数: obj 要获取样式的元素 name 要获取的样式名 function getStyle(obj,name){ if(window.getComputedStyle){ //正常浏览器样式 //.name为获取属性为name,就写死了 return getComputedStyle(obj, null)[name]; } else{ return obj.currentStyle[name];//IE8及以下 } } console.log(getStyle(btn,"backgroundColor"));//rgb(0, 0, 255) } </script> </head> <body> <button type="button" id="btn">我是一个按钮</button> <div > </div> </body> ```

未加window之前,getComputedStyle为函数。如果未找到,全局找——>(没有)报错 加window,未找到返回undefined。

其他的样式相关的属性

clientWidth 、clientHeight 这些属性都是不带px的,返回的都是一个数字,可以直接进行计算,会获取元素宽度和高度,包括内容区和内边距,这些属性都是只读不可修改 alert(box1.clientWidth);

offsetWidth offsetwidth 获取元素的整个宽度和高度,包括内容区、内边距和边框 alert(box1.offsetWidth);

offsetParent 获取当前元素的定位父元素 会获取到离当前元素最近的开启了定位的祖先元素(只要不是position 不是static就开启了定位)如果所有的祖先元素都没有开启定位,则返回body var op=box1.offsetParent; alert(op.id);

offsetLeft 当前元素相对于其定位元素的水平偏移量 offsetTop 当前元素相对于其定位元素的垂直偏移量 scrollHeight-scrollTop=clientHeight scrollWidth-scrollLeft=clientWidth

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> #box1{ width: 200px; height: 200px; background-color: beige; margin: 10px; overflow: auto; } #box2{ width: 400px; height: 300px; } </style> <script type="text/javascript"> window.onload=function(){ //获取box1 var box1=document.getElementById("box1"); var btn=document.getElementById("btn01"); btn.onclick=function(){ alert(box1.offsetLeft);//8 }; }; </script> </head> <body id="body"> <button id="btn01">点我一下</button> <!-- <div id="box2" style="position: relative;"> --> <div id="box1"> <div id="box2"> </div> </div> <!-- </div> --> </body> </html>

事件(Event)

事件对象

onmousemove:该事件将会在鼠标在元素中移动时触发事件对象:当事件的响应对象被触发时,浏览器每次都会将一个事件对象作为参数传递进响应函数。 在事件对象中封装了当前事件相关的一切信息。eg.鼠标的坐标,键盘那个按键被按下,鼠标滚轮移动的方向。clientX 可以获取鼠标指针的水平坐标。 clientY可以获取鼠标指针的竖直坐标。在IE8中,响应函数被触发时,浏览器不会传递事件对象。 在IE8及以下的浏览器中,是将事件对象作为window对象的属性保存的。 div跟随鼠标移动: link. 当鼠标在box1中移动时,box2中显示坐标:link.

事件的冒泡(Bubble)

1.事件的冒泡(Bubble):所谓的冒泡就是指事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发。 在开发中,大部分情况冒泡都是有用的,如果不希望发生冒泡事件,可以通过事件对象来取消冒泡 Event和window.event区别:link.

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> #box1{ width: 200px; height: 200px; background-color: #FF7F50; } #s1{ background-color: antiquewhite; } </style> <script type="text/javascript"> window.onload=function(){ //获取s1,并为其绑定单击响应函数 var span=document.getElementById("s1"); span.onclick=function(event){ event=event||window.event; //取消冒泡 event.cancelBubble=true; alert("我是span的单击响应函数"); } //获取div,并为其绑定单击响应函数 var box1=document.getElementById("box1"); box1.onclick=function(event){ //兼容IE与其他浏览器 event=event||window.event; event.cancelBubble=true; alert("我是div的单击响应函数"); } //获取body,并为其绑定单击响应函数 document.body.onclick=function(){ alert("我是body的单击响应函数"); } } </script> </head> <body> <div id="box1">我是box1 <span id="s1">span</span> </div> </body> </html>

事件的委派

事件的委派:指将事件同意绑定给元素的共同的祖先元素,这样当后代元素上的事件被触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。 事件委派其实利用了冒泡,通过委派可以减少事件绑定的此数,提高程序的性能。

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> //为每一个超链接绑定单击响应函数 window.onload=function(){ //获取ul var ul=document.getElementById("ul"); //为每一个超链接都绑定了一个单机响应函数,操作麻烦,且该操作只能为已有的超链接设置事件 var aAll=document.getElementsByTagName("a"); // //遍历a // for(var i=0;i<aAll.length;i++){ // aAll[i].οnclick=function(){ // alert("我是a的单击响应函数"); // }; // } //希望绑定一次事件,即可应用到多个的元素上,即使元素是后添加的。 //尝试将其绑定给元素的共同的祖先元素 //事件的委派:指将事件同意绑定给元素的共同的祖先元素,这样当后代元素上的事件被触发时,会一直冒泡到祖先元素 //从而通过祖先元素的响应函数来处理事件 // -事件委派其实利用了冒泡,通过委派可以减少事件绑定的此数,提高程序的性能 ul.onclick=function(event){ //但是该区域点击都会响应函数,如果触发事件是期望的元素则执行 event=event||window.event; //target event中的target表示的是触发事件的对象 if(event.target.className="link"){ alert("我是ul的单击响应函数"); } }; //为button绑定单击响应函数 var btn=document.getElementById("btn01"); btn.onclick=function(){ var li=document.createElement("li"); li.innerHTML="<a href='javascript:;' class='link'>>新的超链接</a>"; ul.appendChild(li); }; }; </script> </head> <body> <button id="btn01">创建超链接</button> <ul id="ul"> <li><a href="javascript:;" class="link">超链接一</a></li> <li><a href="javascript:;" class="link">超链接二</a></li> <li><a href="javascript:;" class="link">超链接三</a></li> <li><a href="javascript:;" class="link">超链接四</a></li> </ul> </body> </html>

事件的绑定

使用对象.事件=函数的形式绑定响应函数 它只能同时为一个元素的一个事件绑定一个响应函数,不能绑定多个,如果绑定了多个,则后面会覆盖前面的。 btn01.οnclick=function(){ alert(“hi”); };addEventListener()不支持IE8及以下的浏览器。通过该方法为元素绑定响应函数 ,同时为一个元素的相同事件同时绑定多个响应函数 参数: 1.事件的字符串,不要on 2.回调函数,当事件触发时该函数会被调用 3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false。btn01.addEventListener("click",function(){ alert("hi"); },false); DOM2级事件”规定的事件流包含三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,然后是实际的目标接收到事件,最后阶段是冒泡阶段。 attachEvent()在IE8中可以使用该方法来绑定事件,后绑定先执行。 参数: 1.事件的字符串要on 2.回调函数btn01.attachEvent('onclick',function(){ alert("hi"); });

综合:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> // 点击按钮后弹出一个内容 window.onload=function(){ var btn01=document.getElementById("btn01"); bind(btn01,"click",function(){ alert("1"); }); //定义一个函数,为指定元素绑定响应函数 //addEventListener()中的this.绑定的是事件的对象 //attachEvent()中的this.绑定的是window //统一两个方法this //参数: obj:要绑定事件的对象 eventStr 事件的字符串(不要on) callback 回调函数 function bind(obj,eventStr,callback){ if(obj.addEventListener){ //大部分浏览器兼容 //callback调用的是object HTMLButtonElement obj.addEventListener(eventStr,callback,false); }else{ //this是谁由调用方式决定 //IE及以下 obj.attachEvent("on"+eventStr,function(){ //本来是浏览器调用,现在变成自己调用 //callback调用本来是object window,自己调用 现在是object HTMLButtonElement callback.call(obj); }); } } }; </script> </head> <body> <button id="btn01">点我一下</button> </body> </html>

事件的传播

事件的传播 -关于事件的传播网景公司和微软公司由不同的理解 -微软公司认为事件应该是由内向外传播,即当事件被触发时,应该先触发当前元素上的事件,然后再向上传播 即事件应该再冒泡阶段执行。 -网景公司认为事件应该是由外向内传播的,即当事件触发时,应该先触发当前元素的最外层的祖先元素的事件,然后再向内传递 w3c综合了两个公司的方案,将事件的传播分成了三个阶段。 1.捕获阶段:在该阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件 2.目标阶段:事件捕获到目标元素,捕获结束开始在目标元素上触发事件 3.冒泡阶段:事件从目标元素向它的祖先元素传递,依次触发祖先元素上的事件 如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true,一般情况下不会希望在捕获阶段触发事件

常用事件

鼠标事件

1.onmousewheel鼠标滚轮滚动事件,会在滚轮滚动时触发,火狐不支持。 在火狐中使用DOMMouseScroll来绑定滚动事件 注意该事件需要通过addEventListener()函数来绑定。 2. 向上滚是正值,向下滚是负值 1)event.wheelDelta可以获取鼠标滚轮方向,不看大小,只看正负,火狐不支持。 2)event.detail适用于火狐。 3. 当滚轮滚动时,如果浏览器有滚动条,滚动条随之滚动 这是浏览器的默认行为,如果不希望发生,则可以取消默认行为 4. 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false。 使用event来取消默认行为。 但是IE8不支持event.preventDefault(); event.preventDefault&&event.preventDefault();//实现兼容 完整代码

鼠标实现div拖拽

键盘事件

键盘事件:一般绑定给可以获得焦点的对象或者document。onkeydown:键盘被按下,如果一直按着某个按键不松手,事件会连续触发 -当onkeydown被连续触发时,第一次和第二次间隔会长一点,之后便会很快, 这种设计是为了防止误操作。onkeyup:键盘被松开。可以通过keyCode来获取按键的编码,通过它可以判断那个按键被按下。 除了keyCode,还有altKey ctrlKey shiftKey,如果按下返回true,否则返回false。 完整代码(功能还包括不能输入数字)

BOM

BOM :浏览器对象模型 BOM可以使我们通过JS来操作浏览器,在BOM中为我们提供了一组对象,用来完成对浏览器的操作。BOM对象 1)Window:代表的是整个浏览器的窗口,同时window也是网页中的全局对象。 2)Navigator:代表当前浏览器的信息,通过该对象可以识别不同的浏览器 3)Location:代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面 4)History:代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录 由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问时有效 5)Screen:代表用户屏幕的信息,通过该对象可以获得到用户的显示器的相关的信息 这些BOM对象都是在浏览器中通过window对象的属性保存的 通过window对象来使用,也可以直接使用。

Navigator

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

由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了。因为在IE浏览器中很多地方需要兼容,所有很多网站选择在其他浏览器中最好的展现,在IE中功能完全即可,但用户体验不好就会认为是浏览器不好,在制作网页时,程序员会根据navigator.appName判断显示,结果为Navigator就最好展现, 显示Microsoft Internet Explorer就功能完全即可,所以IE为了挽回名声,在IE11浏览器里,如果使用navigator.appName会发现,显示Navigator,使得被同等对待,提升用户使用体验 一般只会使用userAgent来判断浏览器的信息。 userAgent是一个字符串,其包括有用来描述浏览器信息的内容,不同的浏览器会有不同的userAgent。在IE11中已经将微软和IE相关的标识都已经去除了,所以基本不能通过UserAgent来识别一个浏览器是否是IE了。 判断浏览器信息

History

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

length 属性,可以获取到当次访问的链接的数量 alert(history.length);back() 可以用来回退到上一个页面,作用与浏览器的后退一样。 eg. history.back();forward() 可以用来回退到上一个页面,作用与浏览器的前进一样。go()用来跳转到指定页面,需要一个整数作为页面 1表示向前跳转一个页面 -1表示向后跳转一个页面 2表示向前跳转两个页面

Location

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

如果直接打印Location,则可以获得到地址栏的信息(当前页面的完整路径)如果直接将location属性直接修改为一个完整的路径或相对路径,则页面会自动跳转页面,并会生成相应的历史记录。assign() 用来跳转至其他的页面,作用与直接修改location一样。reload() 重新加载当前页面,作用与刷新按钮一样。 如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面。replace() 使用一个新的页面替换当前页面,使用完毕也会跳转页面。不能使用回退按钮回退。 完整测试代码

window

定时器

JS的程序的执行速度是非常高的,如果希望一段程序每间隔一段时间执行一次,使用定时器。 setInterval():定时调用,可以将一个参数,每隔一段时间执行一次。 参数: 1.回调函数,该函数每隔一段时间执行一次 2.每次调用间隔的时间,单位是毫秒1000毫秒即1秒 返回值:返回一个Number类型的数据,这个数字用来作为定时器的唯一标识

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <script type="text/javascript"> window.onload=function(){ var count=document.getElementById('count'); var num=1; var timer=setInterval(function(){ count.innerHTML=num++; if(num==11){ //关闭定时器 clearInterval(timer); } },500); }; </script> <body> <h1 id="count"></h1> </body> </html>

键盘控制div移动 按钮控制div移动方向 图片切换

延时调用

延时调用:延时一段时间不马上执行,而是隔一段时间后再执行,而且只会执行一次 浏览器打开后有一个大广告,用这个可以在15秒后关闭 延时调用和定时调用实际上是可以互相代替的。

var timer=setTimeout(function(){ alert(num); },1000); //关闭延时调用 //clearTimeout(timer);

JSON

如果需要兼容IE7及以下的JSON操作,则可以通过引入一个外部的js文件来处理。

#原生js

JSON:JS的对象只有JS自己认识,其他的语言都不认识 JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言识别 并且可以转换为任意语言中的对象,在开发中主要用来数据的交互。 JSON(JavaScript Object Notation JS)对象表示法 JSON格式与JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号,其他的与JS语法一致。 JS分类: 1.对象{} 2.数组[] JSON中允许的值:字符串 数值 布尔值 null 对象 数组

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <!-- 如果需要兼容IE7及以下的JSON操作,则可以通过引入一个外部的js文件来处理 --> <script type="text/javascript"> //创建一个对象,属性名加不加引号都可 var obj='{"name":"孙悟空","age":18,"gender":"男"}'; var arr='[1,2,3,"hello"]'; var obj2='{"arr":[1,2,3]}'; console.log(typeof obj);//string /** * JSON字符串转换为对象 * JS中,提供了一个工具类,就叫JSON * 这个对象可以帮我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON * */ var json='{"name":"孙悟空","age":18,"gender":"男"}'; /** * JSON.parse() * 将JSON字符串转换为js对象 * 它需要一个JSON字符串作为对象,会将该字符串转换为JS对象并返回 */ var o=JSON.parse(json); console.log(o.name); var obj3={name:"孙悟空",age:18,gender:"男"}; /** * JS对象转JSON * 需要一个js对象作为参数,会返回一个JSON */ var str=JSON.stringify(obj3.name); console.log(str); /** * JSON对象在IE7及以下不支持 * */ </script>S </head> <body> </body> </html>

other

localStorage

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

eval()

这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回 如果使用eval()执行的字符串中含有{},它会将{}当成是代码块 如果不希望将其当成代码块解析,则需要在字符串前后各加一个()

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

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

注意事项

中文名的html文件在IE中样式会丢失。var img=document.getElementsByTagName(“img”)[0];//不加[0]获取到的为HTMLCollection。
最新回复(0)