Featured image of post JavaScript Learn Part.B

JavaScript Learn Part.B

JavaScript学习笔记二

JS中的事件

常用事件

  • 焦点

    • blur失去焦点
    • focus获得焦点
  • 击打

    • click鼠标单击
    • dblclick鼠标双击
  • 键盘

    • keydown键盘按下
    • keyup键盘弹起
  • 鼠标

    • mousedown鼠标按下
    • mouseover鼠标经过
    • mousemove鼠标移动
    • mouseout鼠标离开
    • mouseup鼠标弹起
  • 表单

    • reset表单重置(在form元素中添加,不是input)
    • submit表单提文
  • 其它

    • select文本被选定
    • change下拉列表选中项改变,或文本框内容改变
    • load页面加载完毕【注意此事件在页面所有元素(包括执行完所有script脚本)加载完毕后触发,不是加载时触发】

参考代码020-事件.

注册事件的2种方式

方法一

在标签中使用事件句柄属性,在事件句柄中编写事件代码, 当对应的事件发生后,注册在事件句柄当中的代码被监听器调用。 一般称事件句柄注册的函数为回调函数(CallBack Function)。 回调函数的特点是:

  1. 监听器负责调用而非程序
  2. 事件发生后监听器来调用

方法二

  • 铺垫:根据id获取节点对象

在JS中有一个隐含的对象document,代表整个HTML文档,是DOM的顶级对象。 在JS中有一个隐含的对象window,代表整个浏览器窗口,是BOM的顶级对象。

document对象有一系列方法,其中getElementById()可根据id名返回节点对象。 在JS中,获取到节点之后,节点属性可以直接当作JS对象的属性访问(读/写)。 因此,可以把写好的函数绑定到事件句柄属性上:obj_onExmapleEvent = myFunction,注意不要写成myFunction()

代码的执行顺序

一般情况下,如果元素未加载而通过id获取对象,会失败,参考022 Line 11。 解决办法:利用表征所有元素加载完成的load事件,参考代码024

当onload句柄的回调函数执行时,所有元素必然加载完毕。 当然这里有一个瑕疵,即load事件句柄的回调函数是用第一种绑定方法,可否改造成第二种?解决办法:利用window对象(暂时可以认为是body标签的对象),为onload绑定函数:window.onload = function(){}, 参考代码026

例子:通过keydown事件捕捉Enter和ESC

目标:输入框输入完成时按下Enter键,要捕捉到回车键按下,并输出提示.

原理:所有回调函数在被监听器调用时,都会传入一个对象参数,表示发生的事件对象。 对于所有的键盘事件,事件对象有keycode属性,可以获取键值。 其中Enter键值是13,Esc键值是27。

运算符void

语法格式:void(表达式)
含义:执行表达式,并且不做任何返回(即使表达式本身有返回结果)

示例代码文件

1
2
3
4
5
6
<h1>H1</h1>
<br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br>
<a href="" onclick="alert('执行JS代码')">保留超链接样式,点击后执行一段JS代码,执行完后保证页面不跳转</a>

按下超链接后页面其实会跳转, 因为href置空默认跳转到本页,也就是一次刷新。 为了不要此次刷新(跳转),关键是要把跳转路径完全干掉, 而不是默认值或者空字符串:

1
2
3
<a href="javascript:void('anything')" onclick="alert('执行JS代码')">
    超链接
</a>

注意到要加javascript:以免浏览器认为"void()“是地址。 可以观察一下鼠标悬停在超链接文本上时浏览器下角会出现“javascript:void(0)”。

控制语句

JS的控制语句和除了Java相同,也有特别的。

  • 选择
    • if
    • switch
  • 循环
    • for
    • while
    • do … while
  • 跳转
    • break
    • continue
    • return

特别的语句,了解即可 ——

for … in 语句

遍历数组,index是下标,类型Number

1
2
3
4
5
6
7
8
var arr = [true, 4, "abc", 2, NaN, 10, 7] 
for (var i=0; i<arr.length; i++) {
    console.log(arr[i])
}
// 另一种遍历, 注意index是索引值的字符串,例如"0", "1"等,类型是String
for (var index in arr) {
    console.log(arr[index])
}

遍历对象属性, prop是属性名,类型String

1
2
3
4
5
6
7
8
9
function Emp(x, y, z) {
    this.propa = x
    this.propb = y
    this.propc = z
}
obj = new Emp(1, "jack", 123.45)
for(var prop in obj) {
    console.log("obj."+prop+" = "+obj[prop])
}

with语句

内置对象

Array

Array是JS的数组类型,数组长度可变。

创建数组

方法1:创建数组时赋值

JS的数组是可变长的,并且如果为越界下标元素赋值,数组将自动扩容到该下标, 并且新扩展的元素除了最后一个被赋值的,其它值默认undefined。

方法2:利用Array类

  • new Array() 创建空数组
  • new Array(4) 创建指定长度空数组
  • new Array(false, NaN, 34.55, 3, 5)

使用for..in或者for来遍历数组,使用下标访问并修改,类型可变。

常用方法

方法 用例 描述
push arr.push(val) 向数组末尾追加元素,返回追加元素
pop arr.pop() 将数组末尾元素弹出并返回之,同时数组长度减一 ;
可以说数组的push和pop遵循栈的行为
reverse arr.reverse() 反转数组,返回数组对象(引用)
join arr.join(s) 将数组元素用字符(串)s连接成字符串

Date

创建Date对象

  • new Date() 返回Date对象,包含系统当前时间
  • new Date(4) // 创建指定长度空数组
  • new Date(false, NaN, 34.55, 3, 5)

Date的方法

方法 描述
getFullYear 返回四位年份
getYear
getMonth 返回值0-11代表1·12月份
getDay 返回星期数, 1-7代表周一到周日
getDate 返回一个月中第几天
getHours 返回小时
getMinutes 返回分钟
getSeconds 返回喵
getMilliseconds 返回毫秒
toLocaleString 转化成本地语言·地区的日期格式
getTime 获取自1970/0/0 0:0:0 000的毫秒数(时间戳)

附录

JavaScript 基础语法练习题一

考察范围:JS概述(Javascript-Learn全部) - 控制语句(JavaScript-Learn-Part.B)

一、单选题(每题2分,共20分)

1 – 关于JavaScript嵌入方式,以下说法错误的是()

A. 行间事件法中`window.alert()`可以简写为`alert()`
B. 引入外部JS文件的`<script>`标签内写代码会正常执行
C. 页面脚本块可以出现在HTML文档的任意位置
D. 多个脚本块会按照在文档中出现的顺序依次执行

2 – 执行typeof null的结果是()

A. null
B. object
C. undefined
D. number

3 – 以下关于JS变量的说法,正确的是()

A. 声明变量时必须指定数据类型
B. `var a;` 执行后a的值为null
C. 函数内未使用var声明的变量是全局变量
D. 变量一旦赋值,类型无法改变

4 – 关于JS函数,以下描述错误的是()

A. 函数调用时实参数量可以和形参数量不一致
B. 可以先调用函数再定义函数
C. JS支持函数重载,同名函数会根据参数区分执行
D. `var sum = function(a,b){return a+b}` 是函数的合法定义方式

5 – 执行isNaN("123abc")的结果是()

A. true
B. false
C. NaN
D. undefined

6 – *以下运算符比较结果为true的是()

A. null === undefined
B. 10 == "10"
C. NaN == NaN
D. 0 === false

7 – 关于事件绑定,以下说法正确的是()

A. `window.onload`事件在页面开始加载时立即触发
B. 通过`document.getElementById()`获取元素时,无需等待DOM加载完成
C. 为元素绑定事件时,函数名后加括号表示绑定函数本身
D. keydown事件中,Enter键的keyCode值为13

8 – 执行parseInt("123.99abc")的结果是()

A. 123.99
B. 123
C. NaN
D. 123.99abc

9 – *关于for…in语句,以下描述错误的是()

A. 遍历数组arr时,`for(var i in arr)`的i是数组下标,类型为Number
B. 遍历对象elt时,`for(var prop in elt)`的prop是属性名,类型String
C. 可以遍历数组的所有元素
D. 可以遍历对象的所有属性

1 –. 以下关于void运算符的用法,正确的是()

A. `void(alert("test"))` 执行后会返回alert的执行结果
B. `<a href="void(0)" onclick="alert('test')">` 可阻止超链接跳转
C. `void`运算符的作用是不执行表达式
D. `<a href="javascript:void(0)" onclick="alert('test')">`可阻止超链接跳转

二、不定项选择题(每题4分,共20分,多选、少选、错选均不得分)

1 – 以下属于JavaScript三大组成部分的有()

A. ECMAScript
B. DOM
C. BOM
D. JQuery

2 – 以下数据类型中,属于JS原始数据类型的有()

A. Undefined
B. Object
C. Boolean
D. Null

3 – 以下字符串方法的描述,正确的有()

A. `length`属性用于获取字符串长度
B. `replace(s1,s2)`会替换字符串中所有的s1
C. `split(",")`可将字符串按逗号拆分为数组
D. `charAt(0)`可获取字符串第一个字符

4 – 以下关于JS事件的描述,正确的有()

A. blur事件表示元素失去焦点
B. submit事件需绑定在form元素上
C. mouseover事件表示鼠标离开元素
D. change事件可监听下拉列表选中项的改变

5 – 以下关于JS对象和原型的描述,正确的有()

A. 可通过`prototype`为Object扩展方法
B. 访问对象属性的方式有`obj.prop`和`obj["prop"]`
C. JS中通过`function`定义的函数可作为类使用
D. `new String("test")`创建的变量类型为String

三、填空题(每空2分,共20分)

  1. JavaScript中,声明变量使用________关键字(ES6前),未赋值的变量默认值为________。
  2. JS中==是________运算符,===是________运算符。
  3. 页面中所有元素加载完毕后触发的事件是________。
  4. isNaN()函数的作用是________,它会首先尝试将参数转换为________类型。
  5. 遍历对象属性的特殊循环语句是________。
  6. 阻止超链接默认跳转行为时,href属性的正确写法是________。
  7. JS中Number类型的特殊值,非数字用________表示,正无穷大用________表示。
  8. 为对象动态扩展属性和方法可使用________属性。
  9. 函数内未使用var声明的变量默认是________变量。
  10. DOM顶级对象是________,BOM顶级对象是________。

四、编程题(每题20分,共60分)

题目1:数字判断与转换

要求:

  1. 编写一个函数checkNumber,接收一个参数;
  2. 判断该参数是否为有效数字(非NaN),若是则返回其整数部分,若不是则返回"不是有效数字”;
  3. 测试用例:
    • checkNumber(“123.45”) → 123
    • checkNumber(“abc”) → “不是有效数字”
    • checkNumber(NaN) → “不是有效数字”
    • checkNumber(99.99) → 99
题目2:事件绑定实现表单验证

要求:

  1. 编写HTML页面,包含一个输入框(id=“username”)和一个按钮(id=“submitBtn”);
  2. 页面加载完成后,通过脚本为按钮绑定点击事件;
  3. 点击按钮时,验证输入框内容:
    • 若为空,弹出提示"用户名不能为空";
    • 若长度小于6,弹出提示"用户名长度不能小于6位";
    • 若验证通过,弹出提示"用户名验证通过"。
  4. 提示:通过元素对象的value属性获取输入的文本
题目3:对象与遍历

要求:

  1. 定义一个表示学生的类Student,包含属性:姓名(name)、年龄(age)、成绩(score,数组类型);
  2. Student类添加方法getAvgScore,用于计算成绩的平均分;
  3. 创建一个Student实例,姓名为"张三",年龄为18,成绩为[80,90,85,95];
  4. 遍历该实例的所有属性并打印(格式:属性名:属性值);
  5. 调用getAvgScore方法,打印平均分。

JavaScript 基础语法练习题一 答案

题号 答案 解析
1 B 引入外部 JS 文件的<script>标签内的代码不会执行
2 B typeof null返回object是 JS 的历史设计 bug
3 C A:JS 是弱类型,声明变量无需指定类型;
B:var a;默认值是 undefined;
D:JS 变量类型可动态改变
4 C JS 不支持函数重载,同名函数仅保留最后定义的版本
5 A “123abc"无法转换为有效数字,isNaN返回 true
6 B A:null和undefined类型不同,全等为 false;
C:NaN 与任何值(包括自身)都不相等;
D:类型不同,全等为 false
7 D A:window.onload在所有元素加载完毕后触发;
B:需等待 DOM 加载完成才能获取元素;
C:加括号会立即执行函数,而非绑定
8 B parseInt从左到右解析,截取整数部分,遇到非数字停止
9 A 遍历数组时,index是字符串类型(如 “0”),需手动转换为数字
10 D A:void执行表达式但无返回值;B:缺少javascript:前缀,
浏览器会认为是普通地址;C:void会执行表达式
11 ABC JS 三大组成部分:ECMAScript(核心)、
DOM(文档对象模型)、BOM(浏览器对象模型);
JQuery 是 JS 库,非核心组成
12 ACD 原始数据类型:Undefined、Number、String、
Boolean、Null;Object 是引用类型
13 ACD B:replace(s1,s2)仅替换首次出现的 s1,全替换需正则表达式
14 ABD C:mouseover是鼠标经过,mouseout是鼠标离开
15 ABC D:new String(“test”)创建的是 Object 类型,
字面量"test"是 String 类型

填空题

  1. var;undefined
  2. 等同;全等
  3. load(或window.onload)
  4. 判断参数是否为非数字;数字
  5. for…in
  6. javascript:void(0)
  7. NaN;Infinity
  8. prototype
  9. 全局
  10. document;window

编程题一

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
function checkNumber(param) {
    // 判断是否为有效数字
    if (!isNaN(param)) {
        // 转换为数字后取整数部分
        return parseInt(param);
    } else {
        return "不是有效数字";
    }
}

// 测试用例
console.log(checkNumber("123.45"));  // 123
console.log(checkNumber("abc"));     // 不是有效数字
console.log(checkNumber(NaN));       // 不是有效数字
console.log(checkNumber(99.99));     // 99

编程题二

 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
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>表单验证</title>
</head>
<body>
    <input type="text" id="username" placeholder="请输入用户名">
    <button id="submitBtn">提交</button>

    <script>
        // 等待页面加载完成
        window.onload = function() {
            // 获取元素
            var usernameInput = document.getElementById("username");
            var submitBtn = document.getElementById("submitBtn");
            
            // 绑定点击事件
            submitBtn.onclick = function() {
                var username = usernameInput.value;
                // 验证为空
                if (username === "") {
                    alert("用户名不能为空");
                } else if (username.length < 6) {
                    alert("用户名长度不能小于6位");
                } else {
                    alert("用户名验证通过");
                }
            }
        }
    </script>
</body>
</html>

编程题三

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 1. 定义Student类
function Student(name, age, score) {
    this.name = name;
    this.age = age;
    this.score = score;
    
    // 2. 添加计算平均分的方法
    this.getAvgScore = function() {
        if (this.score.length === 0) return 0;
        var sum = 0;
        for (var i = 0; i < this.score.length; i++) {
            sum += this.score[i];
        }
        return sum / this.score.length;
    }
}

// 3. 创建实例
var zhangsan = new Student("张三", 18, [80,90,85,95]);

// 4. 遍历实例属性
console.log("学生信息:");
for (var prop in zhangsan) {
    // 排除方法属性(可选,根据需求)
    if (typeof zhangsan[prop] !== "function") {
        console.log(prop + ":" + zhangsan[prop]);
    }
}

// 5. 调用方法并打印平均分
var avgScore = zhangsan.getAvgScore();
console.log("平均分:" + avgScore); // 输出:平均分:87.5
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy