前端基础 & 初识JS(JavaScript)
一、JavaScript概述
JavaScript的历史
-
1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.(客户端执行的语言)
-
Netscape(网景)接收Nombas的理念,(Brendan Eich)在其Netscape Navigator 2.0产品中开发出一套livescript的脚本语言.Sun和Netscape共同完成.后改名叫Javascript
-
微软随后模仿在其IE3.0的产品中搭载了一个JavaScript的克隆版叫Jscript.
-
为了统一三家,ECMA(欧洲计算机制造协会)定义了ECMA-262规范.国际标准化组织及国际电工委员会(ISO/IEC)也采纳 ECMAScript 作为标准(ISO/IEC-16262)。从此,Web 浏览器就开始努力(虽然有着不同的程度的成功和失败)将 ECMAScript 作为 JavaScript 实现的基础。EcmaScript是规范.
ECMAScript
尽管 ECMAScript 是一个重要的标准,但它并不是 JavaScript 唯一的部分,当然,也不是唯一被标准化的部分。实际上,一个完整的 JavaScript 实现是由以下 3 个不同部分组成的:
- 核心(ECMAScript)
- 文档对象模型(DOM) Document object model (整合js,css,html)
- 浏览器对象模型(BOM) Broswer object model(整合js和浏览器)
- Javascript 在开发中绝大多数情况是基于对象的.也是面向对象的.
简单地说,ECMAScript 描述了以下内容:
- 语法
- 类型
- 语句
- 关键字
- 保留字
- 运算符
- 对象 (封装 继承 多态) 基于对象的语言.使用对象.
二、JavaScript的基础
2.1 JS的引入方式
1
2
3
4
5
6
|
1 直接编写 <script> alert( 'hello yuan' ) < / script> 2 导入文件 <script src = "hello.js" >< / script> |
2.2 JS的变量、常量和标识符
2.2.1 JS的变量
1
2
3
|
x = 5 y = 6 z = x + y |
在代数中,我们使用字母(比如 x)来保存值(比如 5)。通过上面的表达式 z=x+y,我们能够计算出 z 的值为 11。在 JavaScript 中,这些字母被称为变量。
那么如何在JS中定义使用变量呢?
1、声明变量时不用声明变量类型. 全都使用var关键字;
1
2
|
var a; a = 3 ; |
2、一行可以声明多个变量.并且可以是不同类型
1
|
var name = "yuan" , age = 20 , job = "lecturer" ; |
3、声明变量时 可以不用var. 如果不用var 那么它是全局变量
4、变量命名,首字符只能是字母,下划线,$美元符 三选一,余下的字符可以是下划线、美元符号或任何字母或数字字符且区分大小写,x与X是两个变量
5 变量还应遵守以下某条著名的命名规则:
1
2
3
4
5
6
7
8
9
|
Camel 标记法 首字母是小写的,接下来的字母都以大写字符开头。例如: var myTestValue = 0 , mySecondValue = "hi" ; Pascal 标记法 首字母是大写的,接下来的字母都以大写字符开头。例如: Var MyTestValue = 0 , MySecondValue = "hi" ; 匈牙利类型标记法 在以 Pascal 标记法命名的变量前附加一个小写字母(或小写字母序列),说明该变量的类型。例如,i 表示整数,s 表示字符串,如下所示“ Var iMyTestValue = 0 , sMySecondValue = "hi" ; |
注意:
1
2
3
4
5
6
7
8
9
10
11
|
function func1(){ var a = 123 ; b = 456 } func1(); / / alert(a); / / alert(b); / / 不推荐 |
2.2 基础规范
1 每行结束可以不加分号. 没有分号会以换行符作为每行的结束
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
a = 1 ;b = 2 ; a = 1 b = 2 ; - - - - - - 错误 a = 1 b = 2 / / 推荐 a = 1 ; b = 2 ; { a = 1 ; b = 2 ; / / 推荐加tab a = 1 ; b = 2 ; } |
2 注释 支持多行注释和单行注释. /* */ //
3 使用{}来封装代码块
2.3 常量和标识符
常量 :直接在程序中出现的数据值
标识符:
- 由不以数字开头的字母、数字、下划线(_)、美元符号($)组成
- 常用于表示函数、变量等的名称
- 例如:_abc,$abc,abc,abc123是标识符,而1abc不是
- JavaScript语言中代表特定含义的词称为保留字,不允许程序再定义为标识符
2.4 数据类型
1
2
3
4
5
6
7
8
|
/ * number - - - - - 数值 boolean - - - - - 布尔值 string - - - - - 字符串 undefined - - - - - undefined null - - - - - null * / |
2.3.1 数字类型(number)
- 不区分整型数值和浮点型数值;
- 所有数字都采用64位浮点格式存储,相当于Java和C语言中的double格式
- 能表示的最大值是±1.7976931348623157 x 10308
- 能表示的最小值是±5 x 10 -324
整数:
在JavaScript中10进制的整数由数字的序列组成
精确表达的范围是
-9007199254740992 (-253) 到 9007199254740992 (253)
超出范围的整数,精确度将受影响
浮点数:
使用小数点记录数据
例如:3.4,5.6
使用指数记录数据
例如:4.3e23 = 4.3 x 1023
16进制和8进制数的表达:
16进制数据前面加上0x,八进制前面加0;16进制数是由0-9,A-F等16个字符组成;8进制数由0-7等8个数字组成
16进制和8进制与2进制的换算:
1
2
|
2 进制: 1111 0011 1101 0100 < - - - - - > 16 进制: 0xF3D4 < - - - - - > 10 进制: 62420 2 进制: 1 111 001 111 010 100 < - - - - - > 8 进制: 0171724 |
2.3.2 字符串类型(string)
1
2
3
4
5
6
7
|
简介 是由 Unicode 字符、数字、标点符号组成的序列 字符串常量首尾由单引号或双引号括起 JavaScript中没有字符类型 常用特殊字符在字符串中的表达 字符串中部分特殊字符必须加上右划线\ 常用的转义字符 \n:换行 \':单引号 \":双引号 \\:右划线 |
String数据类型的使用
- 特殊字符的使用方法和效果
- Unicode的插入方法
1
2
3
4
|
<script> var str = "\u4f60\u597d\n欢迎来到\"JavaScript世界\"" ; alert( str ); < / script> |
2.3.3 布尔类型(boolean)
Boolean类型仅有两个值:true和false,也代表1和0,实际运算中true=1,false=0
布尔值也可以看作on/off、yes/no、1/0对应true/false
Boolean值主要用于JavaScript的控制语句,例如:
1
2
3
4
5
|
if (x = = 1 ){ y = y + 1 ; } else { y = y - 1 ; } |
2.3.4 Null & Undefined类型
Undefined类型
Undefined 类型只有一个值,即 undefined。当声明的变量未初始化时,该变量的默认值是 undefined。
当函数无明确返回值时,返回的也是值 "undefined";
Null类型
另一种只有一个值的类型是 Null,它只有一个专用值 null,即它的字面量。值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的。
尽管这两个值相等,但它们的含义不同。undefined 是声明了变量但未对其初始化时赋予该变量的值,null 则用于表示尚未存在的对象(在讨论 typeof 运算符时,简单地介绍过这一点)。如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null。
var person=new Person()
var person=null
数据类型转换
1
2
3
4
5
6
7
8
9
10
|
JavaScript属于松散类型的程序语言 变量在声明的时候并不需要指定数据类型 变量只有在赋值的时候才会确定数据类型 表达式中包含不同类型数据则在计算过程中会强制进行类别转换 数字 + 字符串:数字转换为字符串 数字 + 布尔值:true转换为 1 ,false转换为 0 字符串 + 布尔值:布尔值转换为字符串true或false |
强制类型转换函数
1
2
3
4
5
|
函数parseInt: 强制转换成整数 例如parseInt( "6.12" ) = 6 ; parseInt(“ 12a ")=12 ; parseInt(“a12" ) = NaN ;parseInt(“ 1a2 ") = 1 函数parseFloat: 强制转换成浮点数 parseFloat( "6.12" ) = 6.12 函数 eval : 将字符串强制转换为表达式并返回结果 eval ( "1+1" ) = 2 ; eval ( "1<2" ) = true |
类型查询函数(typeof)
ECMAScript 提供了 typeof 运算符来判断一个值是否在某种类型的范围内。可以用这种运算符判断一个值是否表示一种原始类型:如果它是原始类型,还可以判断它表示哪种原始类型。
2.4 运算符
ECMAScript 算数运算符
1
2
3
4
5
|
加(+)、 减(-)、 乘( * ) 、除( / ) 、余数( % ) 加、减、乘、除、余数和数学中的运算方法一样 例如: 9 / 2 = 4.5 , 4 * 5 = 20 , 9 % 2 = 1 - 除了可以表示减号还可以表示负号 例如:x = - y + 除了可以表示加法运算还可以用于字符串的连接 例如: "abc" + "def" = "abcdef" |
递增(++) 、递减(--)
1
2
3
4
5
6
7
8
9
|
假如x = 2 ,那么x + + 表达式执行后的值为 3 ,x - - 表达式执行后的值为 1 i + + 相当于i = i + 1 ,i - - 相当于i = i - 1 递增和递减运算符可以放在变量前也可以放在变量后: - - i var i = 1 ; console.log(i + + ); console.log( + + i); console.log(i - - ); console.log( - - i); |
一元加减法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
var a = 1 ; var b = 1 ; a = - a; / / a = - 1 var c = "10" ; alert(typeof (c)); c = + c; / / 类型转换 alert(typeof (c)); / / - - - - - - - - - - - - - - - - - - - var d = "yuan" ; d = + d; alert(d); / / NaN:属于Number类型的一个特殊值,当遇到将字符串转成数字无效时,就会得到一个NaN数据 alert(typeof(d)); / / Number / / NaN特点: var n = NaN; alert(n> 3 ); alert(n< 3 ); alert(n = = 3 ); alert(n = = NaN); alert(n! = NaN); / / NaN参与的所有的运算都是false,除了! = |
ECMAScript 逻辑运算符
1
2
3
4
5
6
7
8
|
等于 ( = = ) 、不等于( ! = ) 、 大于( > ) 、 小于( < )
大于等于(> = ) 、小于等于(< = ) 与 (&&) 、或(||) 、非(!) 1 && 1 = 1 1 || 1 = 1 1 && 0 = 0 1 || 0 = 1 0 && 0 = 0 0 || 0 = 0 ! 0 = 1 ! 1 = 0 |
逻辑 AND 运算符(&&)
逻辑 AND 运算的运算数可以是任何类型的,不止是 Boolean 值。
如果某个运算数不是原始的 Boolean 型值,逻辑 AND 运算并不一定返回 Boolean 值:
- 如果某个运算数是 null,返回 null。
- 如果某个运算数是 NaN,返回 NaN。
- 如果某个运算数是 undefined,返回undefined。
逻辑 OR 运算符(||)
与逻辑 AND 运算符相似,如果某个运算数不是 Boolean 值,逻辑 OR 运算并不一定返回 Boolean 值
ECMAScript 赋值运算符
1
2
3
4
5
6
7
|
赋值 = JavaScript中 = 代表赋值,两个等号 = = 表示判断是否相等 例如,x = 1 表示给x赋值为 1 if (x = = 1 ){...}程序表示当x与 1 相等时 if (x = = “on”){…}程序表示当x与“on”相等时 配合其他运算符形成的简化表达式 例如i + = 1 相当于i = i + 1 ,x& = y相当于x = x&y |
实例:
1
2
3
4
5
6
7
8
9
10
|
= = “ 2 ” = = = “ 2 ” ! = “ 4 ” ! = = “ 4 ” var a = 2 ; var b = 4 ; var c = a<b | - - b> - - a; var c = a<b || - - b> - - a; var c = a<b && - - b> - - a; var c = a<b & - - b> - - a; |
ECMAScript等性运算符
执行类型转换的规则如下:
- 如果一个运算数是 Boolean 值,在检查相等性之前,把它转换成数字值。false 转换成 0,true 为 1。
- 如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。
- 如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。
- 如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。
在比较时,该运算符还遵守下列规则:
- 值 null 和 undefined 相等。
- 在检查相等性时,不能把 null 和 undefined 转换成其他值。
- 如果某个运算数是 NaN,等号将返回 false,非等号将返回 true。
- 如果两个运算数都是对象,那么比较的是它们的引用值。如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。
ECMAScript 关系运算符(重要)
1
2
|
var bResult = "Blue" < "alpha" ; alert(bResult); / / 输出 true |
在上面的例子中,字符串 "Blue" 小于 "alpha",因为字母 B 的字符代码是 66,字母 a 的字符代码是 97。
比较数字和字符串
另一种棘手的状况发生在比较两个字符串形式的数字时,比如:
1
2
|
var bResult = "25" < "3" ; alert(bResult); / / 输出 "true" |
上面这段代码比较的是字符串 "25" 和 "3"。两个运算数都是字符串,所以比较的是它们的字符代码("2" 的字符代码是 50,"3" 的字符代码是 51)。
不过,如果把某个运算数该为数字,那么结果就有趣了:
1
2
|
var bResult = "25" < 3 ; alert(bResult); / / 输出 "false" |
这里,字符串 "25" 将被转换成数字 25,然后与数字 3 进行比较,结果不出所料。
总结:
1
2
|
比较运算符两侧如果一个是数字类型,一个是其他类型,会将其类型转换成数字类型. 比较运算符两侧如果都是字符串类型,比较的是最高位的asc码,如果最高位相等,继续取第二位比较. |
Boolean运算符(重要)
1
2
3
4
5
6
7
|
var temp = new Object (); / / false;[]; 0 ; null; undefined; object (new Object ();) if (temp){ console.log( "yuan" ) } else { console.log( "alex" ) } |
全等号和非全等号
等号和非等号的同类运算符是全等号和非全等号。这两个运算符所做的与等号和非等号相同,只是它们在检查相等性前,不执行类型转换。
2.5 流程控制
if 控制语句
1
2
3
4
5
6
7
8
9
10
11
|
if - else 基本格式 if (表达式){ 语句1; ...... } else { 语句2; ..... } 功能说明 如果表达式的值为true则执行语句 1 , 否则执行语句 2 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
var x = (new Date()).getDay(); / / 获取今天的星期值, 0 为星期天 var y; if ( (x = = 6 ) || (x = = 0 ) ) { y = "周末" ; } else { y = "工作日" ; } alert(y); / / 等价于 y = "工作日" ; if ( (x = = 6 ) || (x = = 0 ) ) { y = "周末" ; } |
if 可以单独使用
1
2
3
4
5
6
7
8
9
10
|
if 语句嵌套格式 if (表达式 1 ) { 语句 1 ; } else if (表达式 2 ){ 语句 2 ; } else if (表达式 3 ){ 语句 3 ; } else { 语句 4 ; } |
1
2
3
4
5
6
7
8
9
10
11
|
if (x = = 1 ){ y = "星期一" ; } else if (x = = 2 ){ y = "星期二" ; ... } else if (x = = 6 ){ y = "星期六" ; } else if (x = = 0 ){ y = "星期日" ; } else { y = "未定义" ; |
switch 选择控制语句
1
2
3
4
5
6
7
|
switch基本格式 switch (表达式) { case 值 1 :语句 1 ; break ; case 值 2 :语句 2 ; break ; case 值 3 :语句 3 ; break ; default:语句 4 ; } |
1
2
3
4
5
6
7
8
9
10
|
switch(x){ case 1 :y = "星期一" ; break ; case 2 :y = "星期二" ; break ; case 3 :y = "星期三" ; break ; case 4 :y = "星期四" ; break ; case 5 :y = "星期五" ; break ; case 6 :y = "星期六" ; break ; case 7 :y = "星期日" ; break ; default: y = "未定义" ; } |
switch比else if结构更加简洁清晰,使程序可读性更强,效率更高。
for 循环控制语句
1
2
3
4
5
6
7
|
for 循环基本格式 for (初始化;条件;增量){ 语句 1 ; ... } 功能说明 实现条件循环,当条件成立时,执行语句 1 ,否则跳出循环体 |
1
2
3
4
5
6
7
8
9
10
|
for (var i = 1 ;i< = 7 ;i + + ){ document.write( "<H" + i + ">hello</H " + i + "> " ); document.write( "<br>" ); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var arr = [ 1 , "hello" ,true] / / var dic = { "1" : "111" } for (var i in arr){ console.log(i) console.log(arr[i]) } |
注意:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
doms = document.getElementsByTagName( "p" ); for (var i in doms){ console.log(i); / / 0 1 2 length item namedItem / / console.log(doms[i]) } / / 循环的是你获取的th一个DOM元素集, for in 用来循环对象的所有属性,dom元素集包含了你上面输出的属性。 / / 如果你只要循环dom对象的话,可以用 for 循环: for (var i = 0 ;i<doms.length;i + + ){ console.log(i) ; / / 0 1 2 / / console.log(doms[i]) } |
结论:for i in 不推荐使用.
while 循环控制语句
1
2
3
4
5
6
7
|
while 循环基本格式 while (条件){ 语句 1 ; ... } 功能说明 运行功能和 for 类似,当条件成立循环执行语句花括号{}内的语句,否则跳出循环 |
1
2
3
4
5
6
7
|
var i = 1 ; while (i< = 7 ) { document.write( "<H" + i + ">hello</H " + i + "> " ); document.write( "<br>" ); i + + ; } / / 循环输出H1到H7的字体大小 |
1
2
3
4
5
6
7
8
9
10
11
12
|
<script language = "JavaScript" > / * sayhello是定义的函数名,前面必须加上function和空格 * / function sayHello(){ var hellostr; var myname = prompt( "请问您贵姓?" , "徐" ); hellostr = "您好," + myname + '小姐,欢迎进入"探索之旅"!' ; alert(hellostr); document.write(hellostr); } / / 这里是对前面定义的函数进行调用 sayHello(); < / script> |
练习:分别用for循环和while循环计算出1-100的和?
异常处理
1
2
3
4
5
6
7
8
9
10
|
try { / / 这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行 } catch (e) { / / 如果 try 代码块中抛出了异常,catch代码块中的代码就会被执行。 / / e是一个局部变量,用来指向Error对象或者其他抛出的对象 } finally { / / 无论 try 中代码是否有异常抛出(甚至是 try 代码块中有 return 语句), finally 代码块中始终会被执行。 } 注:主动抛出异常 throw Error('xxxx') |
三、JavaScript的对象
从传统意义上来说,ECMAScript 并不真正具有类。事实上,除了说明不存在类,在 ECMA-262 中根本没有出现“类”这个词。ECMAScript 定义了“对象定义”,逻辑上等价于其他程序设计语言中的类。
var o = new Object();
对象的概念与分类:
- 由ECMAScript定义的本地对象.独立于宿主环境的 ECMAScript 实现提供的对象.(native object)
- ECMAScript 实现提供的、独立于宿主环境的所有对象,在 ECMAScript 程序开始执行时出现.这意味着开发者不必明确实例化内置对象,它已被实例化了。ECMA-262 只定义了两个内置对象,即 Global 和 Math (它们也是本地对象,根据定义,每个内置对象都是本地对象)。(built-in object)
- 所有非本地对象都是宿主对象(host object),即由 ECMAScript 实现的宿主环境提供的对象。所有 BOM 和 DOM 对象都是宿主对象。
object对象:ECMAScript 中的所有对象都由这个对象继承而来;Object 对象中的所有属性和方法都会出现在其他对象中
1
2
|
ToString() : 返回对象的原始字符串表示。 ValueOf() : 返回最适合该对象的原始值。对于许多对象,该方法返回的值都与 ToString() 的返回值相同。 |
11种内置对象
包括:
Array ,String , Date, Math, Boolean, Number Function, Global, Error, RegExp , Object
简介:
在JavaScript中除了null和undefined以外其他的数据类型都被定义成了对象,也可以用创建对象的方法定义变量,String、Math、Array、Date、RegExp都是JavaScript中重要的内置对象,在JavaScript程序大多数功能都是通过对象实现的
1
2
3
4
5
6
7
8
9
10
|
<script language = "javascript" > var aa = Number.MAX_VALUE; / / 利用数字对象获取可表示最大数 var bb = new String( "hello JavaScript" ); / / 创建字符串对象 var cc = new Date(); / / 创建日期对象 var dd = new Array( "星期一" , "星期二" , "星期三" , "星期四" ); / / 数组对象 < / script> |
String对象
自动创建字符串对象:
1
2
3
|
var str1 = "hello world" ; alert(str1.length); alert(str1.substr( 1 , 5 )); |
调用字符串的对象属性或方法时自动创建对象,用完就丢弃
手工创建字符串对象
1
2
3
|
var str1 = new String( "hello word" ); alert(str1.length); alert(str1.substr( 1 , 3 )); |
采用new创建字符串对象str1,全局有效
String对象的属性
1
2
|
获取字符串长度 length |
var str1="String对象";
var str2="";
alert("str1长度 "+str1.length);
alert("str2长度 "+str2.length);
String对象的方法(1) —— 格式编排方法
格式编排方法返回值列表
1
2
3
4
5
6
7
8
9
|
书写格式: String对象提供了一组针对HTML格式的方法,如x.anchor()返回锚定义字符串<a>x< / a>, x.bold()返回粗体表示字符串<b>x< / b>,x.sup()返回上标格式字符串<sup>x< / sup>。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var x = "xyp" ; var y = "x.italics():" + x.italics(); document.write(y.fontsize( 10 )); / / <font size = "10" >x.italics():<i>yuan< / i>< / font> |
String对象的方法(2)—— 大小写转换
1
2
3
4
5
6
7
8
|
var str1 = "AbcdEfgh" ; var str2 = str1.toLowerCase(); var str3 = str1.toUpperCase(); alert(str2); / / 结果为 "abcdefgh" alert(str3); / / 结果为 "ABCDEFGH" |
String对象的方法(3) —— 获取指定字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
书写格式 x.charAt(index) x.charCodeAt(index) 使用注解 x代表字符串对象 index代表字符位置 index从 0 开始编号 charAt返回index位置的字符 charCodeAt返回index位置的 Unicode 编码 - - - - - - - - - - - - - - - - - - - - - - var str1 = "welcome to the world of JS! 徐二" ; var str2 = str1.charAt( 28 ); var str3 = str1.charCodeAt( 28 ); alert(str2); / / 结果为 "徐" alert(str3); / / 结果为 33489 |
String对象的方法(4)—— 查询字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
/ / 书写格式 / / / / x.indexOf(findstr,index) / / x.lastIndexOf(findstr) / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var str1 = "welcome to the world of JS!" ; var str2 = str1.indexOf( "l" ); var str3 = str1.lastIndexOf( "l" ); alert(str2); / / 结果为 2 alert(str3); / / 结果为 18 / / - - - - - - - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - - - - - - - / / 书写格式 / / / / x.match(regexp) / / / / x.search(regexp) / / / / 使用注解 / / / / x代表字符串对象 / / / / regexp代表正则表达式或字符串 / / / / match返回匹配字符串的数组,如果没有匹配则返回null / / / / search返回匹配字符串的首字符位置索引 / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var str1 = "welcome to the world of JS!" ; var str2 = str1.match( "world" ); var str3 = str1.search( "world" ); alert(str2[ 0 ]); / / 结果为 "world" alert(str3); / / 结果为 15 |
String对象的方法(5) ——子字符串处理
截取子字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
/ / 截取子字符串 / / / / 书写格式 / / / / x.substr(start, length) / / / / x.substring(start, end) / / / / 使用注解 / / / / x代表字符串对象 / / / / start表示开始位置 / / / / length表示截取长度 / / / / end是结束位置加 1 / / / / 第一个字符位置为 0 var str1 = "abcdefgh" ; var str2 = str1.substr( 2 , 4 ); var str3 = str1.substring( 2 , 4 ); alert(str2); / / 结果为 "cdef" alert(str3); / / 结果为 "cd" / / - - - - - - - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - - - - - - - / / x. slice (start, end) var str1 = "abcdefgh" ; var str2 = str1. slice ( 2 , 4 ); var str3 = str1. slice ( 4 ); var str4 = str1. slice ( 2 , - 1 ); var str5 = str1. slice ( - 3 , - 1 ); alert(str2); / / 结果为 "cd" alert(str3); / / 结果为 "efgh" alert(str4); / / 结果为 "cdefg" alert(str5); / / 结果为 "fg" |
替换子字符串
1
2
3
4
5
6
|
/ / x.replace(findstr,tostr) var str1 = "abcdefgh" ; var str2 = str1.replace( "cd" , "aaa" ); alert(str2); / / 结果为 "abaaaefgh" |
分割字符串
1
2
3
4
5
6
|
var str1 = "一,二,三,四,五,六,日" ; var strArray = str1.split( "," ); alert(strArray[ 1 ]); / / 结果为 "二" |
连接字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/ / y = x.concat(addstr) / / / / 使用注解 / / / / x代表字符串对象 / / addstr为添加字符串 / / 返回x + addstr字符串 var str1 = "abcd" ; var str2 = str1.concat( "efgh" ); alert(str2); / / 结果为 "abcdefgh" |
Array对象
创建数组对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Array 对象用于在单个的变量中存储多个值。 语法: 创建方式 1 : var a = [ 1 , 2 , 3 ]; 创建方式 2 : new Array(); / / 创建数组时允许指定元素个数也可以不指定元素个数。 new Array(size); / / if 1 个参数且为数字,即代表size, not content 初始化数组对象: var cnweek = new Array( 7 ); cnweek[ 0 ] = "星期日" ; cnweek[ 1 ] = "星期一" ; ... cnweek[ 6 ] = "星期六" ; new Array(element0, element1, ..., elementn) / / 也可以直接在建立对象时初始化数组元素,元素类型允许不同 var test = new Array( 100 , "a" ,true); |
创建二维数组
1
2
3
4
5
6
7
8
9
10
11
|
var cnweek = new Array( 7 ); for (var i = 0 ;i< = 6 ;i + + ){ cnweek[i] = new Array( 2 ); } cnweek[ 0 ][ 0 ] = "星期日" ; cnweek[ 0 ][ 1 ] = "Sunday" ; cnweek[ 1 ][ 0 ] = "星期一" ; cnweek[ 1 ][ 1 ] = "Monday" ; ... cnweek[ 6 ][ 0 ] = "星期六" ; cnweek[ 6 ][ 1 ] = "Saturday" ; |
Array对象的属性
获取数组元素的个数:length
1
2
3
4
5
6
7
8
9
10
11
12
|
复制代码 var cnweek = new Array( 7 ); cnweek[ 0 ] = "星期日" ; cnweek[ 1 ] = "星期一" ; cnweek[ 2 ] = "星期二" ; cnweek[ 3 ] = "星期三" ; cnweek[ 4 ] = "星期四" ; cnweek[ 5 ] = "星期五" ; cnweek[ 6 ] = "星期六" ; for (var i = 0 ;i<cnweek.length;i + + ){ document.write(cnweek[i] + " | " ); } |
Array对象的方法
连接数组-join方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/ / 书写格式 / / x.join(bystr) / / 使用注解 / / / / x代表数组对象 / / bystr作为连接数组中元素的字符串 / / 返回连接后的字符串 / / 与字符串的split功能刚好相反 var arr1 = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ]; var str1 = arr1.join( "-" ); alert(str1); / / 结果为 "1-2-3-4-5-6-7" |
连接数组-concat方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/ / 连接数组 - concat方法 / / / / x.concat(value,...) var a = [ 1 , 2 , 3 ]; var a = new Array( 1 , 2 , 3 ); var b = a.concat( 4 , 5 ) ; alert(a.toString()); / / 返回结果为 1 , 2 , 3 alert(b.toString()); / / 返回结果为 1 , 2 , 3 , 4 , 5 |
数组排序-reverse sort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
/ / x.reverse() / / x.sort() var arr1 = [ 32 , 12 , 111 , 444 ]; / / var arr1 = [ "a" , "d" , "f" , "c" ]; arr1.reverse(); / / 颠倒数组元素 alert(arr1.toString()); / / 结果为 444 , 111 , 12 , 32 arr1.sort(); / / 排序数组元素 alert(arr1.toString()); / / 结果为 111 , 12 , 32 , 444 / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - arr = [ 1 , 5 , 2 , 100 ]; / / arr.sort(); / / alert(arr); / / 如果就想按着数字比较呢? function intSort(a,b){ if (a>b){ return 1 ; / / - 1 } else if (a<b){ return - 1 ; / / 1 } else { return 0 } } arr.sort(intSort); alert(arr); function IntSort(a,b){ return a - b; } |
数组切片-slice
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/ / x. slice (start, end) / / / / 使用注解 / / / / x代表数组对象 / / start表示开始位置索引 / / end是结束位置下一数组元素索引编号 / / 第一个数组元素索引为 0 / / start、end可为负数, - 1 代表最后一个数组元素 / / end省略则相当于从start位置截取以后所有数组元素 var arr1 = [ 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' ]; var arr2 = arr1. slice ( 2 , 4 ); var arr3 = arr1. slice ( 4 ); var arr4 = arr1. slice ( 2 , - 1 ); alert(arr2.toString()); / / 结果为 "c,d" alert(arr3.toString()); / / 结果为 "e,f,g,h" alert(arr4.toString()); / / 结果为 "c,d,e,f,g" |
删除子数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/ / x. splice(start, deleteCount, value, ...) / / / / 使用注解 / / / / x代表数组对象 / / splice的主要用途是对数组指定位置进行删除和插入 / / start表示开始位置索引 / / deleteCount删除数组元素的个数 / / value表示在删除位置插入的数组元素 / / value参数可以省略 var a = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ]; a.splice( 1 , 2 ); / / a变为 [ 1 , 4 , 5 , 6 , 7 , 8 ] alert(a.toString()); a.splice( 1 , 1 ); / / a变为[ 1 , 5 , 6 , 7 , 8 ] alert(a.toString()); a.splice( 1 , 0 , 2 , 3 ); / / a变为[ 1 , 2 , 3 , 5 , 6 , 7 , 8 ] alert(a.toString()); |
数组的进出栈操作(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/ / push pop这两个方法模拟的是一个栈操作 / / x.push(value, ...) 压栈 / / x.pop() 弹栈 / / 使用注解 / / / / x代表数组对象 / / value可以为字符串、数字、数组等任何值 / / push是将value值添加到数组x的结尾 / / pop是将数组x的最后一个元素删除 var arr1 = [ 1 , 2 , 3 ]; arr1.push( 4 , 5 ); alert(arr1); / / 结果为 "1,2,3,4,5" arr1.push([ 6 , 7 ]); alert(arr1) / / 结果为 "1,2,3,4,5,6,7" arr1.pop(); alert(arr1); / / 结果为 "1,2,3,4,5" |
数组的进出栈操作(2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/ / unshift shift / / x.unshift(value,...) / / x.shift() / / 使用注解 / / / / x代表数组对象 / / value可以为字符串、数字、数组等任何值 / / unshift是将value值插入到数组x的开始 / / shift是将数组x的第一个元素删除 var arr1 = [ 1 , 2 , 3 ]; arr1.unshift( 4 , 5 ); alert(arr1); / / 结果为 "4,5,1,2,3" arr1. unshift([ 6 , 7 ]); alert(arr1); / / 结果为 "6,7,4,5,1,2,3" arr1.shift(); alert(arr1); / / 结果为 "4,5,1,2,3" |
总结js的数组特性:
1
2
3
4
5
6
7
8
9
|
/ / js中数组的特性 / / java中数组的特性, 规定是什么类型的数组,就只能装什么类型.只有一种类型. / / js中的数组特性 1 : js中的数组可以装任意类型,没有任何限制. / / js中的数组特性 2 : js中的数组,长度是随着下标变化的.用到多长就有多长. var arr5 = [ 'abc' , 123 , 1.14 ,true,null,undefined,new String( '1213' ),new Function( 'a' , 'b' , 'alert(a+b)' )]; / * alert(arr5.length); / / 8 arr5[ 10 ] = "hahaha" ; alert(arr5.length); / / 11 alert(arr5[ 9 ]); / / undefined * / |
Date对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/ / 方法 1 :不指定参数 var nowd1 = new Date(); alert(nowd1.toLocaleString( )); / / 方法 2 :参数为日期字符串 var nowd2 = new Date( "2004/3/20 11:12" ); alert(nowd2.toLocaleString( )); var nowd3 = new Date( "04/03/20 11:12" ); alert(nowd3.toLocaleString( )); / / 方法 3 :参数为毫秒数 var nowd3 = new Date( 5000 ); alert(nowd3.toLocaleString( )); alert(nowd3.toUTCString()); / / 方法 4 :参数为年月日小时分钟秒毫秒 var nowd4 = new Date( 2004 , 2 , 20 , 11 , 12 , 0 , 300 ); alert(nowd4.toLocaleString( )); / / 毫秒并不直接显示 |
Date对象的方法—获取日期和时间
toLocaleString() 方法可根据本地时间把 Date 对象转换为字符串,并返回结果。
1
2
3
4
5
6
7
8
9
10
11
|
获取日期和时间 getDate() 获取日 getDay () 获取星期 getMonth () 获取月( 0 - 11 ) getFullYear () 获取完整年份 getYear () 获取年 getHours () 获取小时 getMinutes () 获取分钟 getSeconds () 获取秒 getMilliseconds () 获取毫秒 getTime () 返回累计毫秒数(从 1970 / 1 / 1 午夜) |
练习实例:
function getCurrentDate(){ //1. 创建Date对象 var date = new Date(); //没有填入任何参数那么就是当前时间 //2. 获得当前年份 var year = date.getFullYear(); //3. 获得当前月份 js中月份是从0到11. var month = date.getMonth()+1; //4. 获得当前日 var day = date.getDate(); //5. 获得当前小时 var hour = date.getHours(); //6. 获得当前分钟 var min = date.getMinutes(); //7. 获得当前秒 var sec = date.getSeconds(); //8. 获得当前星期 var week = date.getDay(); //没有getWeek // 2014年06月18日 15:40:30 星期三 return year+"年"+changeNum(month)+"月"+day+"日 "+hour+":"+min+":"+sec+" "+parseWeek(week); } alert(getCurrentDate()); //解决 自动补齐成两位数字的方法 function changeNum(num){ if(num < 10){ return "0"+num; }else{ return num; } } //将数字 0~6 转换成 星期日到星期六 function parseWeek(week){ var arr = ["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]; // 0 1 2 3 ............. return arr[week]; }
Date对象的方法—设置日期和时间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
/ / 设置日期和时间 / / setDate(day_of_month) 设置日 / / setMonth (month) 设置月 / / setFullYear (year) 设置年 / / setHours (hour) 设置小时 / / setMinutes (minute) 设置分钟 / / setSeconds (second) 设置秒 / / setMillliseconds (ms) 设置毫秒( 0 - 999 ) / / setTime (allms) 设置累计毫秒(从 1970 / 1 / 1 午夜) var x = new Date(); x.setFullYear ( 1997 ); / / 设置年 1997 x.setMonth( 7 ); / / 设置月 7 x.setDate( 1 ); / / 设置日 1 x.setHours( 5 ); / / 设置小时 5 x.setMinutes( 12 ); / / 设置分钟 12 x.setSeconds( 54 ); / / 设置秒 54 x.setMilliseconds( 230 ); / / 设置毫秒 230 document.write(x.toLocaleString( ) + "<br>" ); / / 返回 1997 年 8 月 1 日 5 点 12 分 54 秒 x.setTime( 870409430000 ); / / 设置累计毫秒数 document.write(x.toLocaleString( ) + "<br>" ); / / 返回 1997 年 8 月 1 日 12 点 23 分 50 秒 |
Date对象的方法—日期和时间的转换
1
2
3
4
5
6
7
8
9
10
11
12
|
日期和时间的转换: getTimezoneOffset(): 8 个时区× 15 度× 4 分 / 度 = 480 ; 返回本地时间与GMT的时间差,以分钟为单位 toUTCString() 返回国际标准时间字符串 toLocalString() 返回本地格式时间字符串 Date.parse(x) 返回累计毫秒数(从 1970 / 1 / 1 午夜到本地时间) Date.UTC(x) 返回累计毫秒数(从 1970 / 1 / 1 午夜到国际时间) |
RegExp对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
/ / RegExp对象 / / 在表单验证时使用该对象验证用户填入的字符串是否符合规则. / / 创建正则对象方式 1 参数 1 正则表达式 参数 2 验证模式 g global / i 忽略大小写. / / 参数 2 一般填写g就可以,也有“gi”. / / 用户名 首字母必须是英文, 除了第一位其他只能是英文数字和_ . 长度最短不能少于 6 位 最长不能超过 12 位 / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - 创建方式 1 / * var reg1 = new RegExp( "^[a-zA-Z][a-zA-Z0-9_]{5,11}$" , "g" ); / / / / 验证字符串 var str = "bc123" ; alert(reg1.test( str )); / / true / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - 创建方式 2 / 填写正则表达式 / 匹配模式; var reg2 = / ^[a - zA - Z][a - zA - Z0 - 9_ ]{ 5 , 11 }$ / g; alert(reg2.test( str )); / / true * / / / - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 正则对象的方法 - - - - - - - - - - - - - - - - - - - / / test方法 = = > 测试一个字符串是否复合 正则规则. 返回值是true 和false. / / - - - - - - - - - - - - - - - - - - - - - - - - - String 中与正则结合的 4 个方法 - - - - - - - - - - - - - - - - - - . / / macth search split replace var str = "hello world" ; / / alert( str .match( / o / g)); / / 查找字符串中 复合正则的 内容. / / alert( str .search( / h / g)); / / 0 查找字符串中符合正则表达式的内容位置 / / alert( str .split( / o / g)); / / 按照正则表达式对字符串进行切割. 返回数组; alert( str .replace( / o / g, "s" )); / / hells wsrld 对字符串按照正则进行替换. |
Math对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
/ / Math对象 / / 该对象中的属性方法 和数学有关. / / Math是内置对象 , 与Global的不同之处是, 在调用时 需要打出 "Math." 前缀. / / 属性学习: / / alert(Math.PI); / / 方法学习: / / alert(Math.random()); / / 获得随机数 0 ~ 1 不包括 1. / / alert(Math. round ( 1.5 )); / / 四舍五入 / / 练习:获取 1 - 100 的随机整数,包括 1 和 100 / / var num = Math.random(); / / num = num * 10 ; / / num = Math. round (num); / / alert(num) / / = = = = = = = = = = = = max min = = = = = = = = = = = = = = = = = = = = = = = = = / * alert(Math. max ( 1 , 2 )); / / 2 alert(Math. min ( 1 , 2 )); / / 1 * / / / - - - - - - - - - - - - - pow - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - alert(Math. pow ( 2 , 4 )); / / pow 计算参数 1 的参数 2 次方. abs (x) 返回数的绝对值。 exp(x) 返回 e 的指数。 floor(x)对数进行下舍入。 log(x) 返回数的自然对数(底为e)。 max (x,y) 返回 x 和 y 中的最高值。 min (x,y) 返回 x 和 y 中的最低值。 pow (x,y) 返回 x 的 y 次幂。 random() 返回 0 ~ 1 之间的随机数。 round (x) 把数四舍五入为最接近的整数。 sin(x) 返回数的正弦。 sqrt(x) 返回数的平方根。 tan(x) 返回角的正切。 |
Function 对象(重点)
函数的定义:
1
2
3
|
function 函数名 (参数){
函数体; return 返回值; } |
功能说明:
- 可以使用变量、常量或表达式作为函数调用的参数
- 函数由关键字function定义
- 函数名的定义规则与标识符一致,大小写是敏感的
- 返回值必须使用return
Function 类可以表示开发者定义的任何函数。
用 Function 类直接创建函数的语法如下:
1
2
3
4
5
6
|
function 函数名 (参数){
函数体; return 返回值; } / / another way: var 函数名 = new Function( "参数1" , "参数n" , "function_body" ); |
虽然由于字符串的关系,第二种形式写起来有些困难,但有助于理解函数只不过是一种引用类型,它们的行为与用 Function 类明确创建的函数行为是相同的。
实例:
1
2
3
4
5
6
7
8
9
10
11
12
|
alert( 1 ); function func1(){ alert( 'hello yuan!' ); return 8 } ret = func1(); alert(ret) ---------------- var func1 = new Function( "name" , "alert(\"hello\"+name);" ) func1( "yuan" ) |
注意:js的函数加载执行与python不同,它是整体加载完才会执行,所以执行函数放在函数声明上面或下面都可以:
1
2
3
4
5
6
7
8
9
10
|
<script> / / f(); - - - >OK function f(){ console.log( "hello" ) } f() / / - - - - - >OK < / script> |
Function 对象的 length 属性
如前所述,函数属于引用类型,所以它们也有属性和方法。
比如,ECMAScript 定义的属性 length 声明了函数期望的参数个数。
1
|
alert(func1.length) |
Function 对象的方法
Function 对象也有与所有对象共享的 valueOf() 方法和 toString() 方法。这两个方法返回的都是函数的源代码,在调试时尤其有用。
1
|
alert(void(fun1( 1 , 2 ))) |
运算符void()作用:拦截方法的返回值
函数的调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
function func1(a,b){ alert(a + b); } func1( 1 , 2 ); / / 3 func1( 1 , 2 , 3 ); / / 3 func1( 1 ); / / NaN func1(); / / NaN / / 只要函数名写对即可,参数怎么填都不报错. - - - - - - - - - - - - - - - - - - - 面试题 - - - - - - - - - - - function a(a,b){ alert(a + b); } var a = 1 ; var b = 2 ; a(a,b) |
函数的内置对象arguments
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
function add(a,b){ console.log(a + b); / / 3 console.log(arguments.length); / / 2 console.log(arguments); / / [ 1 , 2 ] } add( 1 , 2 ) - - - - - - - - - - - - - - - - - - arguments的用处 1 - - - - - - - - - - - - - - - - - - function nxAdd(){ var result = 0 ; for (var num in arguments){ result + = arguments[num] } alert(result) } nxAdd( 1 , 2 , 3 , 4 , 5 ) / / - - - - - - - - - - - - - - - - - - arguments的用处 2 - - - - - - - - - - - - - - - - - - function f(a,b,c){ if (arguments.length! = 3 ){ throw new Error( "function f called with " + arguments.length + " arguments,but it just need 3 arguments" ) } else { alert( "success!" ) } } f( 1 , 2 , 3 , 4 , 5 ) |
匿名函数
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/ / 匿名函数 var func = function(arg){ return "tony" ; } / / 匿名函数的应用 (function(){ alert( "tony" ); } )() (function(arg){ console.log(arg); })( '123' ) |
函数的作用域链和闭包
作用域
js的作用域和py相似,if while等控制语句并没有自己作用域;而函数是有自己的作用域的;
1
2
3
4
5
6
7
8
9
10
11
12
|
if ( 1 = = 1 ){ var s = 12 ; } console.log(s); / / 12 / / - - - - - - - - - - - - - - - - - - - - - - function f(){ var temp = 666 ; } f(); console.log(temp); / / Uncaught ReferenceError: temp is not defined |
嵌套函数的作用域:
例1:
1
2
3
4
5
6
7
8
9
10
11
|
var city = 'beijing' ; function func(){ var city = 'shanghai' ; function inner(){ var city = 'shenzhen' ; console.log(city); } inner(); } func(); |
例2:
1
2
3
4
5
6
7
8
9
10
11
|
var city = 'beijing' ; function Bar(){ console.log(city); } function func(){ var city = 'shanghai' ; return Bar; } var ret = func(); ret(); / / beijing |
闭包:
1
2
3
4
5
6
7
8
9
10
11
12
|
var city = 'beijing' ; function func(){ var city = "shanghai" ; function inner(){ / / var city = "langfang" ; console.log(city); } return inner; } var ret = func(); ret(); |
思考题1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
var city = 'beijing' ; function func(){ var city = "shanghai" ; function inner(){ / / var city = "langfang" ; console.log(city); } return inner; } var ret = func(); ret(); var city = 'beijing' ; function Bar(){ console.log(city); } function func(){ var city = 'shanghai' ; return Bar; } var ret = func(); ret(); / / beijing |
作用域链(Scope Chain):
在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
1
2
3
4
5
6
7
8
9
10
11
12
|
var x = 1 ; function foo() { var y = 2 ; function bar() { var z = 3 ; } } #bar的作用域链: barScopeChain=[bar.AO, foo.AO, global.VO]; #foo的作用域链: fooScopeChain=[foo.Ao, global.VO]; |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
什么是AO,VO? 在函数创建时,每个函数都会创建一个活动对象Active Object (AO),全局对象为Global Object (VO),创建函数的过程也就是为这个对象添加属性的过程,作用域链就是由这些绑定了属性的活动对象构成的。 例如:找x变量;bar函数在搜寻变量x的过程中,先从自身AO对象上找,如果bar.AO存在这个属性,那么会直接使用这个属性的值,如果不存在,则会转到父级函数的AO对象,也就是foo.AO 如果找到x属性则使用,找不到继续 在 global .VO对象查找,找到x的属性,返回属性值。如果在 global .VO中没有找到,则会抛出异常ReferenceError 执行上下文。 函数在执行时会创建一个称为“执行上下文(execution context)”的内部对象,执行上下文定义了函数 执行时的环境。每个执行上下文都有自己的作用域链,用于标识符解析,当执行上下文被创建时,而它的作用 域链初始化为当前运行函数的[[Scope]]所包含的对象。 函数执行 在函数执行过程中,每遇到一个变量,都会检索从哪里获取和存储数据,该过程从作用域链头部,也就是从活 动对象开始搜索,查找同名的标识符,如果找到了就使用这个标识符对应的变量,如果没有则继续搜索作用域 链中的下一个对象,如果搜索完所有对象都未找到,则认为该标识符未定义,函数执行过程中,每个标识符都 要经历这样的搜索过程。 |
创建作用域链的过程
1
2
3
4
5
6
7
8
9
10
11
12
|
函数进入全局,创建VO对象,绑定x属性<入栈> global .VO = {x = underfind; foo:reference of function}(这里只是预解析,为AO对象绑定声明的属性,函数执行时才会执行赋值语句,所以值是underfind) 遇到foo函数,创建foo.AO,绑定y属性<入栈> foo.AO = {y = underfind, bar:reference of function} 遇到bar函数,创建bar.AO,绑定z属性<入栈> bar.AO = {z:underfind} 作用域链和执行上下文都会保存在堆栈中,所以: bar函数的scope chain为:[ 0 ]bar.AO - - >[ 1 ]foo.AO - - >[ 2 ] global .VO foo函数的scope chain为:[ 0 ]foo.AO - - >[ 1 ] global .Vo / / 建议:少定义全局变量 / / 理由:因为作用域链是栈的结构,全局变量在栈底,每次访问全局变量都会遍历一次栈, / / 这样会影响效率 |
函数的scope等于自身的AO对象加上父级的scope,也可以理解为一个函数的作用域等于自身活动对象加上父级作用域.
函数执行前后的作用域链:
注意:作用域链的非自己部分在函数对象被建立(函数声明、函数表达式)的时候建立,而不需要等到执行
思考题2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
for (var i = 1 ; i< = 9 ; i + + ) { setTimeout( function timer(){ console.log( i ); }, 1000 ); } / / ================== for (var i = 1 ; i< = 9 ; i + + ) { (function(){ var j = i; setTimeout( function timer(){ console.log( j ); }, 1000 ); })(); |
四、BOM对象
BOM(浏览器对象模型),可以对浏览器窗口进行访问和操作。使用 BOM,开发者可以移动窗口、改变状态栏中的文本以及执行其他与页面内容不直接相关的动作。
使 JavaScript 有能力与浏览器“对话”。
window对象
1
2
3
4
5
|
window对象 所有浏览器都支持 window 对象。 概念上讲.一个html文档对应一个window对象. 功能上讲: 控制浏览器窗口的. 使用上讲: window对象不需要创建对象,直接使用即可. |
Window 对象方法
1
2
3
4
5
6
7
8
9
10
11
|
alert() 显示带有一段消息和一个确认按钮的警告框。 confirm() 显示带有一段消息以及确认按钮和取消按钮的对话框。 prompt() 显示可提示用户输入的对话框。 open () 打开一个新的浏览器窗口或查找一个已命名的窗口。 close() 关闭浏览器窗口。 setInterval() 按照指定的周期(以毫秒计)来调用函数或计算表达式。 clearInterval() 取消由 setInterval() 设置的 timeout。 setTimeout() 在指定的毫秒数后调用函数或计算表达式。 clearTimeout() 取消由 setTimeout() 方法设置的 timeout。 scrollTo() 把内容滚动到指定的坐标。 |
1、alert confirm prompt以及open函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/ / - - - - - - - - - - alert confirm prompt - - - - - - - - - - - - - - - - - - - - - - - - - - - - / / alert( 'aaa' ); / * var result = confirm( "您确定要删除吗?" ); alert(result); * / / / prompt 参数 1 : 提示信息. 参数 2 :输入框的默认值. 返回值是用户输入的内容. / / var result = prompt( "请输入一个数字!" , "haha" ); / / alert(result); 方法讲解: / / open 方法 打开和一个新的窗口 并 进入指定网址.参数 1 : 网址. / / 调用方式 1 / / open ( "http://www.baidu.com" ); / / 参数 1 什么都不填 就是打开一个新窗口. 参数 2. 填入新窗口的名字(一般可以不填). 参数 3 : 新打开窗口的参数. open (' ',' ',' width = 200 ,resizable = no,height = 100 '); / / 新打开一个宽为 200 高为 100 的窗口 / / close方法 将当前文档窗口关闭. / / close(); |
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
var num = Math. round (Math.random() * 100 ); function acceptInput(){ / / 2. 让用户输入(prompt) 并接受 用户输入结果 var userNum = prompt( "请输入一个0~100之间的数字!" , "0" ); / / 3. 将用户输入的值与 随机数进行比较 if (isNaN( + userNum)){ / / 用户输入的无效(重复 2 , 3 步骤) alert( "请输入有效数字!" ); acceptInput(); } else if (userNum > num){ / / 大了 = = > 提示用户大了,让用户重新输入(重复 2 , 3 步骤) alert( "您输入的大了!" ); acceptInput(); } else if (userNum < num){ / / 小了 = = > 提示用户小了,让用户重新输入(重复 2 , 3 步骤) alert( "您输入的小了!" ); acceptInput(); } else { / / 答对了 = = >提示用户答对了 , 询问用户是否继续游戏(confirm). var result = confirm( "恭喜您!答对了,是否继续游戏?" ); if (result){ / / 是 = = > 重复 123 步骤. num = Math. round (Math.random() * 100 ); acceptInput(); } else { / / 否 = = > 关闭窗口(close方法). close(); } } } |
2、setInterval,clearInterval
setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。
1
2
3
|
语法: setInterval(code,millisec) 其中,code为要调用的函数或要执行的代码串。millisec周期性执行或调用 code 之间的时间间隔,以毫秒计。 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
< input id = "ID1" type = "text" onclick = "begin()" > <button onclick = "end()" >停止< / button> <script> function showTime(){ var nowd2 = new Date().toLocaleString(); var temp = document.getElementById( "ID1" ); temp.value = nowd2; } var clock; function begin(){ if (clock = = undefined){ showTime(); clock = setInterval(showTime, 1000 ); } } function end(){ clearInterval(clock); } < / script> |
setTimeout clearTimeout
1
2
3
4
5
|
var ID = setTimeout(abc, 2000 ); / / 只调用一次对应函数. clearTimeout( ID ); function abc(){ alert( 'aaa' ); } |
五、History 对象
History 对象属性
History 对象包含用户(在浏览器窗口中)访问过的 URL。
History 对象是 window 对象的一部分,可通过 window.history 属性对其进行访问。
1
|
length 返回浏览器历史列表中的 URL 数量。 |
History 对象方法
1
2
3
|
back() 加载 history 列表中的前一个 URL。 forward() 加载 history 列表中的下一个 URL。 go() 加载 history 列表中的某个具体页面。 |
1
2
3
4
|
<a href = "rrr.html" >click< / a> <button onclick = " history.forward()" >>>>< / button> <button onclick = "history.back()" >back< / button> <button onclick = "history.go()" >back< / button> |
六、Location 对象
Location 对象包含有关当前 URL 的信息。
Location 对象是 Window 对象的一个部分,可通过 window.location 属性来访问。
Location 对象方法
1
2
3
|
location.assign(URL) # 跳转指定URL<br>location.href='/classes/' # 要跳转的页面 location. reload () # 刷新当前页面 location.replace(newURL) / / 注意与assign的区别,新的url页面替换当前url页面 |
七、DOM对象(DHTML)
什么是 DOM?
DOM 是 W3C(万维网联盟)的标准。DOM 定义了访问 HTML 和 XML 文档的标准:
"W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。"
W3C DOM 标准被分为 3 个不同的部分:
- 核心 DOM - 针对任何结构化文档的标准模型
- XML DOM - 针对 XML 文档的标准模型
- HTML DOM - 针对 HTML 文档的标准模型
- 什么是 XML DOM? ---->XML DOM 定义了所有 XML 元素的对象和属性,以及访问它们的方法。
- 什么是 HTML DOM?---->HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。
什么是HTML DOM?
- HTML Document Object Model(文档对象模型)
- HTML DOM 定义了访问和操作HTML文档的标准方法
- HTML DOM 把 HTML 文档呈现为带有元素、属性和文本的树结构(节点树)
DOM树
画dom树是为了展示文档中各个对象之间的关系,用于对象的导航。
DOM节点
节点类型
HTML 文档中的每个成分都是一个节点。
DOM 是这样规定的:
整个文档是一个文档节点
每个 HTML 标签是一个元素节点
包含在 HTML 元素中的文本是文本节点
每一个 HTML 属性是一个属性节点
其中,document与element节点是重点。
节点关系
节点树中的节点彼此拥有层级关系。
父(parent),子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。
- 在节点树中,顶端节点被称为根(root)
- 每个节点都有父节点、除了根(它没有父节点)
- 一个节点可拥有任意数量的子
- 同胞是拥有相同父节点的节点
下面的图片展示了节点树的一部分,以及节点之间的关系:
访问 HTML 元素(节点),访问 HTML 元素等同于访问节点,我们能够以不同的方式来访问 HTML 元素。
节点查找
直接查找节点
1
2
3
4
|
document.getElementById(“idname”) document.getElementsByTagName(“tagname”) document.getElementsByName(“name”) document.getElementsByClassName(“name”) |
局部查找
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<div id = "div1" > <div class = "div2" >i am div2< / div> <div name = "yuan" >i am div2< / div> <div id = "div3" >i am div2< / div> <p>hello p< / p> < / div> <script> var div1 = document.getElementById( "div1" ); / / / / 支持; / / var ele = div1.getElementsByTagName( "p" ); / / alert(ele.length); / / / / 支持 / / var ele2 = div1.getElementsByClassName( "div2" ); / / alert(ele2.length); / / / / 不支持 / / var ele3 = div1.getElementById( "div3" ); / / alert(ele3.length); / / / / 不支持 / / var ele4 = div1.getElementsByName( "yuan" ); / / alert(ele4.length) < / script> |
注意:设计到寻找元素,注意<script>标签的位置!
导航节点属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
''' parentElement // 父节点标签元素 children // 所有子标签 firstElementChild // 第一个子标签元素 lastElementChild // 最后一个子标签元素 nextElementtSibling // 下一个兄弟标签元素 previousElementSibling // 上一个兄弟标签元素 ''' |
注意,js中没有办法找到所有的兄弟标签!
节点操作
创建节点:
1
|
createElement(标签名) :创建一个指定名称的元素。 |
例:var tag=document.createElement(“input")
tag.setAttribute('type','text');
添加节点:
1
2
3
4
5
|
追加一个子节点(作为最后的子节点) somenode.appendChild(newnode) 把增加的节点放到某个节点的前边 somenode.insertBefore(newnode,某个节点); |
删除节点:
1
|
removeChild():获得要删除的元素,通过父元素调用删除 |
替换节点:
1
|
somenode.replaceChild(newnode, 某个节点); |
节点属性操作:
1、获取文本节点的值:innerText innerHTML
2、attribute操作
1
2
3
4
5
|
elementNode.setAttribute(name,value) elementNode.getAttribute(属性名) < - - - - - - - - - - - - - - >elementNode.属性名(DHTML) elementNode.removeAttribute(“属性名”); |
3、value获取当前选中的value值
1.input
2.select (selectedIndex)
3.textarea
4、innerHTML 给节点添加html代码:
该方法不是w3c的标准,但是主流浏览器支持
tag.innerHTML = “<p>要显示内容</p>”;
5、关于class的操作:
1
2
3
|
elementNode.className elementNode.classList.add elementNode.classList.remove |
6、改变css样式:
1
2
3
|
<p id = "p2" >Hello world!< / p> document.getElementById( "p2" ).style.color = "blue" ; .style.fontSize = 48px |
DOM Event(事件)
事件类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
onclick 当用户点击某个对象时调用的事件句柄。 ondblclick 当用户双击某个对象时调用的事件句柄。 onfocus 元素获得焦点。 练习:输入框 onblur 元素失去焦点。 应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证. onchange 域的内容被改变。 应用场景:通常用于表单元素,当元素内容被改变时触发.(三级联动) onkeydown 某个键盘按键被按下。 应用场景: 当用户在最后一个输入框按下回车按键时,表单提交. onkeypress 某个键盘按键被按下并松开。 onkeyup 某个键盘按键被松开。 onload 一张页面或一幅图像完成加载。 onmousedown 鼠标按钮被按下。 onmousemove 鼠标被移动。 onmouseout 鼠标从某元素移开。 onmouseover 鼠标移到某元素之上。 onmouseleave 鼠标从元素离开 onselect 文本被选中。 onsubmit 确认按钮被点击。 |
绑定事件方式
方式1:
1
2
3
4
5
6
7
8
|
<div id = "div" onclick = "foo(this)" >点我呀< / div> <script> function foo( self ){ / / 形参不能是this; console.log( "点你大爷!" ); console.log( self ); } < / script> |
方式2:
1
2
3
4
5
6
7
8
9
10
11
12
|
<p id = "abc" >试一试!< / p> <script> var ele = document.getElementById( "abc" ); ele.onclick = function(){ console.log( "ok" ); console.log(this); / / this直接用 }; < / script> |
事件介绍
1、onload:
onload 属性开发中 只给 body元素加.这个属性的触发 标志着 页面内容被加载完成.应用场景: 当有些事情我们希望页面加载完立刻执行,那么可以使用该事件属性.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> <script> / * window.onload = function(){ var ele = document.getElementById( "ppp" ); ele.onclick = function(){ alert( 123 ) }; }; * / function fun() { var ele = document.getElementById( "ppp" ); ele.onclick = function(){ alert( 123 ) }; } < / script> < / head> <body onload = "fun()" > <p id = "ppp" >hello p< / p> < / body> < / html> |
2、onsubmit:
当表单在提交时触发. 该属性也只能给form元素使用.应用场景: 在表单提交前验证用户输入是否正确.如果验证失败.在该方法中我们应该阻止表单的提交.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> <script> window.onload = function(){ / / 阻止表单提交方式 1 (). / / onsubmit 命名的事件函数,可以接受返回值. 其中返回false表示拦截表单提交.其他为放行. var ele = document.getElementById( "form" ); ele.onsubmit = function(event) { / / alert( "验证失败 表单不会提交!" ); / / return false; / / 阻止表单提交方式 2 event.preventDefault(); = = >通知浏览器不要执行与事件关联的默认动作。 alert( "验证失败 表单不会提交!" ); event.preventDefault(); } }; < / script> < / head> <body> <form id = "form" > < input type = "text" / > < input type = "submit" value = "点我!" / > < / form> < / body> < / html> |
3、事件传播:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<div id = "abc_1" style = "border:1px solid red;width:300px;height:300px;" > <div id = "abc_2" style = "border:1px solid red;width:200px;height:200px;" > < / div> < / div> <script type = "text/javascript" > document.getElementById( "abc_1" ).onclick = function(){ alert( '111' ); }; document.getElementById( "abc_2" ).onclick = function(event){ alert( '222' ); event.stopPropagation(); / / 阻止事件向外层div传播. } < / script> |
4、onselect:
1
2
3
4
5
6
7
8
9
10
|
< input type = "text" > <script> var ele = document.getElementsByTagName( "input" )[ 0 ]; ele.onselect = function(){ alert( 123 ); } < / script> |
5、onchange:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<select name = " " id=" "> <option value = ""> 111 < / option> <option value = ""> 222 < / option> <option value = ""> 333 < / option> < / select> <script> var ele = document.getElementsByTagName( "select" )[ 0 ]; ele.onchange = function(){ alert( 123 ); } < / script> |
6、onkeydown:
Event 对象:Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!event对象在事件发生时系统已经创建好了,并且会在事件函数被调用时传给事件函数.我们获得仅仅需要接收一下即可.比如onkeydown,我们想知道哪个键被按下了,需要问下event对象的属性,这里就时KeyCode.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
< input type = "text" id = "t1" / > <script type = "text/javascript" > var ele = document.getElementById( "t1" ); ele.onkeydown = function(e){ e = e||window.event; var keynum = e.keyCode; var keychar = String.fromCharCode(keynum); alert(keynum + '----->' + keychar); }; < / script> |
7、onmouseout与onmouseleave事件的区别:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
<!DOCTYPE html> <html lang = "en" > <head> <meta charset = "UTF-8" > <title>Title< / title> <style> #container{ width: 300px ; } #title{ cursor: pointer; background: #ccc; } #list{ display: none; background: #fff; } #list div{ line - height: 50px ; } #list .item1{ background - color: green; } #list .item2{ background - color: rebeccapurple; } #list .item3{ background - color: lemonchiffon; } < / style> < / head> <body> <p>先看下使用mouseout的效果:< / p> <div id = "container" > <div id = "title" >使用了mouseout事件↓< / div> <div id = "list" > <div class = "item1" >第一行< / div> <div class = "item2" >第二行< / div> <div class = "item3" >第三行< / div> < / div> < / div> <script> / / 1. 不论鼠标指针离开被选元素还是任何子元素,都会触发 mouseout 事件。 / / 2. 只有在鼠标指针离开被选元素时,才会触发 mouseleave 事件。 var container = document.getElementById( "container" ); var title = document.getElementById( "title" ); var list = document.getElementById( "list" ); title.onmouseover = function(){ list .style.display = "block" ; }; container.onmouseleave = function(){ / / 改为mouseout试一下 list .style.display = "none" ; }; / * 因为mouseout事件是会冒泡的,也就是onmouseout事件可能被同时绑定到了container的子元素title和 list 上,所以鼠标移出每个子元素时也都会触发我们的 list .style.display = "none" ; * / / * 思考: if : list .onmouseout = function(){ list .style.display = "none" ; }; 为什么移出第一行时,整个 list 会被隐藏? 其实是同样的道理,onmouseout事件被同时绑定到 list 和它的三个子元素item上,所以离开任何一个 子元素同样会触发 list .style.display = "none" ; * / < / script> < / body> < / html> |
八、实例练习
1、搜索框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script> function Focus(){ var input=document.getElementById("ID1"); if (input.value=="请输入用户名"){ input.value=""; } } function Blurs(){ var ele=document.getElementById("ID1"); var val=ele.value; if(!val.trim()){ ele.value="请输入用户名"; } } </script> </head> <body> <input id="ID1" type="text" value="请输入用户名" onblur="Blurs()" onfocus="Focus()"> </body> </html>
2、模态对话框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .back{ background-color: white; height: 2000px; } .shade{ position: fixed; top: 0; bottom: 0; left:0; right: 0; background-color: grey; opacity: 0.4; } .hide{ display: none; } .models{ position: fixed; top: 50%; left: 50%; margin-left: -100px; margin-top: -100px; height: 200px; width: 200px; background-color: wheat; } </style> </head> <body> <div class="back"> <input class="c" type="button" value="click"> </div> <div class="shade hide handles"></div> <div class="models hide handles"> <input class="c" type="button" value="cancel"> </div> <script> var eles=document.getElementsByClassName("c"); var handles=document.getElementsByClassName("handles"); for(var i=0;i<eles.length;i++){ eles[i].onclick=function(){ if(this.value=="click"){ for(var j=0;j<handles.length;j++){ handles[j].classList.remove("hide"); } } else { for(var j=0;j<handles.length;j++){ handles[j].classList.add("hide"); } } } } </script> </body> </html>
3、表格案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <button class="select_all">全选</button> <button class="select_reverse">反选</button> <button class="cancel">取消</button> <hr> <table class="server_table" border="2px" cellspacing="2px"> <tr> <td><input type="checkbox" class="item"></td> <td>111</td> <td>111</td> <td>111</td> </tr> <tr> <td><input type="checkbox" class="item"></td> <td>222</td> <td>222</td> <td>222</td> </tr> <tr> <td><input type="checkbox" class="item"></td> <td>333</td> <td>333</td> <td>333</td> </tr> <tr> <td><input type="checkbox" class="item"></td> <td>444</td> <td>444</td> <td>444</td> </tr> </table> <script> /* var ele_all=document.getElementsByClassName("select_all")[0]; var ele_reverse=document.getElementsByClassName("select_reverse")[0]; var ele_cancel=document.getElementsByClassName("cancel")[0]; var input_arr=document.getElementsByClassName("item"); ele_all.onclick=function(){ for(var i=0;i<input_arr.length;i++){ console.log(input_arr[i]); var input=input_arr[i]; input.checked=true; } }; ele_cancel.onclick=function(){ for(var i=0;i<input_arr.length;i++){ console.log(input_arr[i]); var input=input_arr[i]; input.checked=false; } }; ele_reverse.onclick=function(){ for(var i=0;i<input_arr.length;i++){ console.log(input_arr[i]); var input=input_arr[i]; if(input.checked){ input.checked=false; } else{ input.checked=true; } } }; */ var input_arr=document.getElementsByClassName("item"); var button_arr=document.getElementsByTagName("button"); for(var i=0;i<button_arr.length;i++){ button_arr[i].onclick=function(){ for (var j=0;j<input_arr.length;j++){ var inp=input_arr[j] if(this.innerText=="全选"){ console.log("ok"); inp.checked=true; } else if(this.innerText=="取消"){ inp.checked=false; } else { if(inp.checked){ inp.checked=false; }else { inp.checked=true; } } } } } </script> </body> </html>
4、select移动
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .outer{ margin: 0 auto; background-color: darkgray; width: 80%; height: 600px;margin-top: 30px; word-spacing: -5px; } #left{ display: inline-block; width: 100px ; height: 140px; background-color: wheat; text-align: center; } #choice{ display: inline-block; height: 140px; background-color: darkolivegreen; vertical-align: top; padding:0 5px; } #choice button{ margin-top: 20px; } #right{ display: inline-block; width: 100px ; height: 140px; background-color: wheat; text-align: center; line-height: 140px; } </style> </head> <body> <div class="outer"> <select multiple="multiple" size="5" id="left"> <option>红楼梦</option> <option>西游记</option> <option>水浒传</option> <option>JinPingMei</option> <option>三国演义</option> </select> <span id="choice"> <button id="choose_move"> > </button><br> <button id="all_move"> >> </button> </span> <select multiple="multiple" size="10" id="right"> <option>放风筝的人</option> </select> </div> <script> var choose_move=document.getElementById("choose_move"); var all_move=document.getElementById("all_move"); var right=document.getElementById("right"); var left=document.getElementById("left"); var options=left.options; choose_move.onclick=function(){ for (var i=0; i<options.length;i++){ var option=options[i]; if(option.selected==true){ // var news=option.cloneNode(true); // console.log(news); right.appendChild(option); i--; } } }; all_move.onclick=function(){ for (var i=0; i<options.length;i++){ var option=options[i]; right.appendChild(option); i--; }; }; /* var buttons=document.getElementsByTagName("button"); for(var i=0;i<buttons.length;i++) { buttons[i].onclick = function () { for (var i = 0; i < options.length; i++) { var option = options[i]; if (this.innerText == ">") { if (option.selected == true) { // var news=option.cloneNode(true); // console.log(news); right.appendChild(option); i--; } } else { right.appendChild(option); i--; } } }; } */ </script> </body> </html>
5、二级联动
<select id="province"> <option>请选择省:</option> </select> <select id="city"> <option>请选择市:</option> </select> <script> data={"河北省":["廊坊","邯郸"],"北京":["朝阳区","海淀区"]}; var p=document.getElementById("province"); var c=document.getElementById("city"); for(var i in data){ var option_pro=document.createElement("option"); option_pro.innerHTML=i; p.appendChild(option_pro); } p.onchange=function(){ pro=(this.options[this.selectedIndex]).innerHTML; citys=data[pro]; c.options.length=0; for (var i in citys){ var option_city=document.createElement("option"); option_city.innerHTML=citys[i]; c.appendChild(option_city); } } </script>
6、跑马灯与tab切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>tab</title> <style> *{margin:0; padding:0; list-style:none;} body{ font-family: "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei", "\9ED1\4F53", Arial, sans-serif; } h3{ text-align: center; color:darkcyan; margin-top: 30px; letter-spacing: 5px; } .box{ width: 1000px; margin:50px auto 0px; } #title{ line-height: 40px; background-color: rgb(247,247,247); font-size: 16px; font-weight: bold; color: rgb(102,102,102); } #title span{ float: left; width: 166px; text-align: center; } #title span:hover{ /*color: black;*/ cursor: pointer; } #content{ margin-top: 20px; } #content li{ width: 1050px; display: none; background-color: rgb(247,247,247); } #content li div{ width: 156px; margin-right: 14px; float: left; text-align: center; } #content li div a{ font-size: 14px; color: black; line-height: 14px; /* float: left;*/ display: inline-block; margin-top: 10px; } #content li a:hover{ color: #B70606; } #content li div span{ font-size: 16px; line-height: 16px; /*float: left;*/ display: block; color: rgb(102,102,102); margin-top: 10px; } #content img{ float: left; width: 155px; height: 250px; } #title .select{ background-color: #2459a2; color: white; border-radius: 10%; } #content .show{ display: block; } .show span{ color: red!important; font-size: 30px; } </style> </head> <body> <h3 id="wel">京东商城欢迎您</h3> <!-- direction="right up down left" --> <!-- behavior:滚动方式(包括3个值:scroll、slide、alternate) --> <!-- 说明:scroll:循环滚动,默认效果;slide:只滚动一次就停止;alternate:来回交替进行滚动。 --> <!-- scrollamount="5" 滚动速度 --> <marquee behavior="scroll" direction="right">欢迎您苑昊先生</marquee> <script> function test(){ var mywel = document.getElementById("wel"); var content = mywel.innerText; var f_content = content.charAt(0); var l_content = content.substring(1,content.length); var new_content = l_content + f_content; mywel.innerText = new_content; } // setInterval("test();", 500); </script> <div class="box"> <p id="title"> <span class="select">家用电器</span> <span>家具</span> <span>汽车</span> <span>食品</span> <span>女鞋</span> <span>医疗保健</span> </p> <ul id="content"> <li class="show"> <div><img src="https://img10.360buyimg.com/n1/s450x450_jfs/t4786/325/2470647304/119102/9e1a4ed5/59005841Nd786a8df.jpg" alt="冰箱"><a href="#">容声(Ronshen)冰箱</a><span>价格:5600</span></div> <div><img src="https://img12.360buyimg.com/n1/s450x450_jfs/t3037/347/1290968859/201366/7c1028a0/57c00194N9d0a54c6.jpg" alt="洗衣机"><a href="#">海尔洗衣机</a><span>价格:5400</span></div> <div><img src="https://img11.360buyimg.com/n1/jfs/t3289/128/2393835119/236360/af1d283b/57e0f300N53dde603.jpg" alt="电饭煲"><a href="#">福库(CUCKOO)电饭煲</a><span>价格:3999</span></div> <div><img src="https://img13.360buyimg.com/n1/jfs/t3235/137/2361713777/152258/a6908440/57e098c2N44a90a5d.jpg" alt="智能电视"><a href="#">三星智能电视</a><span>价格:8999</span></div> <div><img src="https://img10.360buyimg.com/n1/jfs/t2053/101/1391591157/215066/572e131b/5696ee9bN2376492d.jpg" alt="净水器"><a href="#">净水器</a><span>价格:1300</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t3175/78/2357430273/262835/9a8e7f65/57e0a3e9Nbda39dd2.jpg" alt="空气净化器"><a href="#">空气净化器</a><span>价格:5300</span></div> </li> <li> <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div> <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div> <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div> <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div> <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div> <div><img src="https://img12.360buyimg.com/n1/jfs/t1948/172/2877517581/556924/682eb107/56f63dc8Naddf77e5.jpg" alt="沙发"><a href="#">沙发</a><span>价格:2900</span></div> </li> <li> <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div> <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div> <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div> <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div> <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div> <div><img src="http://img11.360buyimg.com/n1/jfs/t4969/76/45396935/144539/347153d4/58d9cff4N36872ad6.jpg" alt="长安汽车"><a href="#">长安汽车</a><span>价格:12900</span></div> </li> <li> <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t4414/110/2582917360/207971/b7e129ad/58f0ee1fN94425de1.jpg" alt="嘉兴粽子"><a href="#">嘉兴粽子</a><span>价格:1</span></div> </li> <li> <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div> <div><img src="https://img14.360buyimg.com/n1/jfs/t3079/298/5759209435/92674/14818594/587f1c33N53e5d2a9.jpg" alt="星期六"><a href="#">星期六</a><span>价格:439</span></div> </li> <li> <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div> <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div> <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div> <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div> <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div> <div><img src="https://img12.360buyimg.com/n1/jfs/t5755/127/1139389729/356866/99d4e869/5923e410Nb2983f70.jpg" alt="汇仁 肾宝片"><a href="#">汇仁 肾宝片</a><span>价格:322</span></div> </li> </ul> </div> <script> var title=document.getElementById('title'); var content=document.getElementById('content'); var category=title.getElementsByTagName('span'); var item=content.getElementsByTagName('li'); for (var i = 0; i < category.length; i++) { category[i].index=i; category[i].onclick=function(){ for (var j = 0; j < category.length; j++) { category[j].className=''; item[j].className=''; } this.className='select'; item[this.index].className='show'; } } </script> </body> </html>
九、js扩展
js的作用域
作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理。
任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。
作用域
1. 全局作用域(Global Scope)
在代码中任何地方都能访问到的对象拥有全局作用域,一般来说一下几种情形拥有全局作用域:
(1)最外层函数和在最外层函数外面定义的变量拥有全局作用域
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var name = "yuan" ; function foo(){ var age = 23 ; function inner(){ console.log(age); } inner(); } console.log(name); / / yuan / / console.log(age); / / Uncaught ReferenceError: age is not defined foo(); / / 23 inner(); / / Uncaught ReferenceError: inner is not defined |
(2)所有末定义直接赋值的变量自动声明为拥有全局作用域,例如:
1
2
3
4
5
6
7
8
9
10
|
var name = "yuan" ; function foo(){ age = 23 ; var sex = "male" } foo(); console.log(age); / / 23 console.log(sex); / / sex is not defined |
变量blog拥有全局作用域,而sex在函数外部无法访问到。
(3)所有window对象的属性拥有全局作用域
一般情况下,window对象的内置属性都都拥有全局作用域,例如window.alert()、window.location、window.top等等。
2. 局部作用域(Local Scope)
和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所有在一些地方也会看到有人把这种作用域成为函数作用域.
如示例1中的age与inner都只有局部作用域。(js中if、for没有自己的作用域)
作用域链(Scope Chain)
在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
示例演示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
/ / - - - - - * * * * * * * * * * * * * * * * * * * * * * 例 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * var s = 12 ; function f(){ console.log(s); var s = 12 ; / / if s = 12 console.log(s) } f(); / / - - - - - * * * * * * * * * * * * * * * * * * * * * * 例 2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * var s = 10 ; function foo(){ console.log(s); var s = 5 ; console.log(s); function s(){console.log( "ok" )} / / 函数的定于或声明是在词法分析时完成的,执行时已不再有任何操作 console.log(s); } foo(); / / - - - - - * * * * * * * * * * * * * * * * * * * * * * * 例 3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * function bar(age) { console.log(age); var age = 99 ; var sex = 'male' ; console.log(age); function age() { alert( 123 ) }; console.log(age); return 100 ; } result = bar( 5 ); / / - - - - - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
结果分析
我相信大家一定会有想不到的结果,接下来我们就以最复杂的例3来分析整个过程。
当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。在函数bar创建时,它的作用域链中会填入一个全局对象,该全局对象包含了所有全局变量,如下图所示:
解析到函数调用时,即bar(5),会生成一个active object的对象,该对象包含了函数的所有局部变量、命名参数、参数集合以及this,然后此对象会被推入作用域链的前端,当运行期上下文被销毁,活动对象也随之销毁。新的作用域链如下图所示:
过程解析:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
function bar(age) { console.log(age); var age = 99 ; var sex = "male" ; console.log(age); function age(){ alert( 123 ); } ; console.log(age); return 100 ; } result = bar( 5 ); 一 词法分析过程(涉及参数,局部变量声明,函数声明表达式): 1 - 1 、分析参数,有一个参数,形成一个 AO.age = undefine; 1 - 2 、接收参数 AO.age = 5 ; 1 - 3 、分析变量声明,有一个 var age, 发现 AO 上面有一个 AO.age ,则不做任何处理 1 - 4 、分析变量声明,有一个 var sex,形成一个 AO.sex = undefine; 1 - 5 、分析函数声明,有一个 function age(){} 声明, 则把原有的 age 覆盖成 AO.age = function(){}; 二 执行过程: 2 - 1 、执行第一个 console.log(age) 时,当前的 AO.age 是一个函数,所以输出的一个函数 2 - 2 、这句 var age = 99 ; 是对不 AO.age 的属性赋值, AO.age = 99 ,所以在第二个输出的age是 99 ; 2 - 3 、同理第三个输出的是 99 , 因为中间没有改变 age 值的语句了。 注意:执行阶段: function age(){ alert( 123 ) } ; 不进行任何操作,将执行语句复制给age这部操作是在词法分析时,即运行前完成的。 |
abs(x) 返回数的绝对值。 exp(x) 返回 e 的指数。 floor(x)对数进行下舍入。 log(x) 返回数的自然对数(底为e)。 max(x,y) 返回 x 和 y 中的最高值。 min(x,y) 返回 x 和 y 中的最低值。 pow(x,y) 返回 x 的 y 次幂。 random() 返回 0 ~ 1 之间的随机数。 round(x) 把数四舍五入为最接近的整数。 sin(x) 返回数的正弦。 sqrt(x) 返回数的平方根。 tan(x) 返回角的正切。