JavaScript入门经典(第7版)读书笔记
断断续续看了十来天,终于看完了,还是学到些东西,这本书还是不错的,各方面都有涉及。
补充了下之前不完善的JS 知识
笔记一般只记必要的东西。
Table of Contents
- 1. JavaScript 基础
- 2. JavaScript 编程
- 3. 理解 JavaScript 对象
- 4. 用 JavaScript 操作 Web 界面
- 5. 与 JavaScript 工具相关的高级技术
- 6. 专业技能
1 JavaScript 基础
1.1 JavaScript 简介
1.2 创建简单的脚本
1.2.1 在 Web 页面里添加 JavaScript
- 把代码放在 script 标签内
- 通过 src 引用外部 js 文件
1.2.3 变量
1.3 使用函数
1.3.1 基本语法
1.4 函数的更多知识
1.4.2 箭头函数
var sayHello = function() { alert("hello"); }; var sayHello = () => alert('hello'); var myFunc = x => alert(x); myFunc = (x, y) => alert(x + y); myFunc = (x, y, z) => { let area = x*y + 5; let boxes = area / z; return boxes; }
1.4.3 设置默认参数
1.5 DOM 对象和内置对象
1.5.1 与用户交互
1.5.2 根据 id 选择元素
var myDiv = document.getElementById("div1");
1.5.3 访问浏览器历史记录
alert(history.length); history.forward(); history.backward(); history.go(-3); history.go(2); history.go("baidu.com");
1.5.4 使用 location 对象
- location 的属性 .href .protocol .host .hostnmae .port .pathname .search .hash
- 用 location 对象导航
- 两种导航到新页面的方式 location.href = “www.baidu.com”; location.replace(“www.baidu.com”); 前者会保留旧页面在历史记录里
- 刷新页面
- location.reload(); 避免使用缓存 location.reload(true);
- 获取浏览器信息: navigator 对象
- navigator 保留浏览器本身的数据
- navigator 的属性 .appName .appCodeName .appVersion .language .cookieEnabled .cpuClass .onLine .platform .plugins.length
- navigator 返回的信息并不准确
1.5.5 日期和时间
- 创建具有当前日期和时间的 Date 对象
var mydate = new Date(); var year = mydate.getFullYear(); var month = mydate.getMonth(); var date = mydate.getDate(); var day = mydate.getDay(); // 星期 var hours = mydate.getHours(); var minutes = mydate.getMinutes(); var seconds = mydate.getSeconds();
- 创建具有指定日期和时间的 Date 对象
var d1 = new Date("October 22, 1995 10:57:22"); var d2 = new Date(95, 9, 22); var d3 = new Date(95, 9, 22, 10, 57, 0);
- 设置和编辑日期与时间
var mydate = new Date(); document.write(mydate.getDay()); mydate.setDate(15); document.write(mydate.getDat()); document.write(mydate.toDateString() + mydate.toTimeString());
- 利用 Math 对象简化运算
- Math 的一些常见方法 .ceil(n) .floor(n) .max(a, b, c, …) .min(a, b, c, …) .round(n) 四舍五入 .random() 返回一个 0 到 1 的随机数
- 取整
- 获得最大值和最小值
- 生成随机数
function myRand(range) { return Math.round(Math.random() * range); }
- 数字常数
.E 自然常数,约为 2.718 .LN2 2 的自然对数,约为 0.693 .LN10 10 的自然对数,约为 2.302 .LOG2E 以 2 为底 e 的对数,约为 1.442 .LOG10E 以 10 为底 e 的对数,约为 0.434 .PI 圆周率,约为 3.14159 .SQRT12 2 的平方根的倒数,约为 0.707 .SQRT2 2 的平方根,约为 1.414
- 关键字 with
with (Math) { var myRand = random(); var biggest = max(2, 3, 5); var height = round(11.22); }
2 JavaScript 编程
2.1 数字和字符串
2.1.2 全局方法
2.1.3 Number 对象
- Number.isNaN()
- 当试图把一些非数值当做数值处理,却无法得到数值时,返回值就是 NaN
-
示例
Number.isNaN(3); //false Number.isNaN(0 / 0); // true
- Number.isInteger()
- Number.parseFloat() 和 Number.parseInt()
- 解析的字符串首字符如果是一个数字,函数会持续解析到数字结束
Number.parseFloat("21.4"); // 21.4 Number.parseInt("12px",10); // 12
- 无穷大
- 表示无穷的关键字 Infinity -Infinity
- isFinite() 会把参数转换为数值,如果结果是 NaN,正无穷大或负无穷大,函数返回 false
2.1.4 Number() 函数
- 该函数会尽可能返回一个对等的数值,如果失败,返回 NaN
2.1.5 布尔值
- 如果布尔值被用作计算,true 为 1, false 为 0
- JS 里被当做 false 的值
- 布尔值 false
- 未定义 undefined
- null
- 0
- NaN
- “”
2.1.6 null(空) 和 undefined(未定义)
- undefined 不是关键字,是未定义的全局变量
2.2 操作字符串
2.2.1 字符串
2.2.2 模板字符串
var name = "aa"; var course = "bb"; var myString = `hell ${name}, welcome ${course}`;
2.3 数组
2.3.1 数组
- JS 的数组能够存放任何数据类型
- 创建新数组
- 数组也是一个对象 var myArray = new Array(); var myArray = [];
- 初始化数组
var myArray = ['111', '22']; myArray[20] = "333e"; myArray.length
- 数组的方法
- concat
- join 把数组的全部元素连接在一起形成一个字符串 var longDay = myArray.join(“-”);
- toString 相当于 myArray.join(“,”);
- indexOf 没有找到返回-1
- lastIndexOf
- slice 可以为负数
- sort 把数组元素按字母顺序排列
- splice myArray.splice(2, 1, “heheda”); 指向索引为 2 的元素,删除 1 个元素,插入一个新元素,返回被删除的元素
2.3.2 如何遍历数组
- 使用 forEach()
-
接受一个函数作为参数,并将函数依次应用与数组中的每个元素
var myArray = [1, 2, 3, 4]; function cube(x) { console.log(x*x*x); } myArray.forEach(cube);
- forEach 不返回任何值
-
- 使用 map()
-
和 forEach 的区别在于 map 会返回和最初数组相同大小的新数组
var myArray = [1, 2, 3, 4]; fucntion cube(x) { return (x*x*x); } var newArray = myArray.map(cube);
-
- 使用 for-of 访问数组
var myArray = [2,3,4,5]; functionn cube(x) { console.log(x*x*x); } for (var y of myArray) { cube(y); }
2.4 用 JavaScript 处理事件
- mousedown 和 mouseup 在 click 前触发
- ctrlKey shiftKey altKey metaKey
2.4.1 事件的类型
- 一些常见事件
- 鼠标事件
- onclick
- oncontextmenu 鼠标右键弹出菜单
- ondblclick
- onmousedown
- onmouseenter 鼠标移动到一个元素上时
- onmouseleave
- onmousemove 鼠标在一个元素上移动时
- onmouseover 鼠标移动到一个元素或其子元素时
- 键盘事件
- onkeydown 按下按键
- onkeypress 按下并放开按键
- onkeyup 释放按键
- DOM 对象事件
- onerror 加载一个外部文件出现错误时
- onload
- onresize
- onscroll 滚动了元素的滚动条
- 表单事件
- onblur 元素失去焦点时
- onchange
- onfocus
- onreset 重置表单
- onselect
- onsubmit
- 鼠标事件
2.4.2 事件处理器
- 内联事件处理器
<a href="http://www.baidu.com" onclick="alert('hello')">baidu</a>
- 作为 DOM 对象的属性的事件处理器
// <a href="xxx" id="a1">aa</a> var myLink = document.getElementById('a1'); myLink.onclick = function() { alert("hello"); }
- 使用 addEventListener()
var myLink = document.getElementById('a1'); function sayHello() { alert("hello"); } myLink.addEventListener('click', sayHello); myLink.removeEventListener('click', sayHello);
- 添加多个监听器
- 使用 addEventListener 可以对一个事件添加多个函数
2.4.3 event 对象
myInputField = document.getElementById('a'); function myFunction(e) { var kc = e.keyCode; if (kc == 27) { alert("xx"); } } myInputField.addEventListener('keydown', myFunction);
- event 对象会自动传递给事件处理器
- e.keyCode 表示按下了哪个键,27 表示 Escape
- 阻止默认行为
var myLink = document.getElementById('a'); function refuseAccess(e) { alert("wrong"); e.preventDefault(); } myLink.addEventListener('click', refuseAccess);
- 事件冒泡和捕获
- 嵌套元素时,各层元素都有事件监听器时,执行顺序为冒泡
- addEventListener 的第三个参数默认为 false,对于嵌套元素,从内向外执行,像冒泡一样.
- 关闭冒泡和捕获
function myFunction(e) { var kc = e.keyCode; e.stopPropagation(); if (kc == 27) { alert("1"); } }
2.5 程序控制
2.5.2 循环和控制结构
2.5.3 设置和使用定时器
- 这两个方法都是 window 对象的方法
- setTimeout()
function hide(elementId) { document.getElementById(elementId).style.display='none'; } window.onload = function() { setTimtout("hide('id1')", 3000); } var timer1 = setTimeout("hide('id1')", 3000); clearTimeout(timer1);
- setInterval()
var timer1 = setInterval("updateClock()", 1000); clearInterval(timer1);
3 理解 JavaScript 对象
3.1 面向对象编程
3.1.1 什么是面向对象编程
3.1.2 创建对象
- 创建直接实例
myNewObject = new Object(); myNewObject.showInfo = myFunc; myNewObject.info = 'this is a info';
- 使用关键字 this
- this 在 HTML 内联 JS 里指此 HTML 元素,也可指向它所属的对象
- 匿名函数
myNewObject.showInfo = function() { alert(this.info); }
- 使用构造函数
-
如果要创建一个类的多个实例,可以创建构造函数
function Car(Color, Year, Make, Miles) { this.color = Color; this.year = Year; this.make = Make; this.odometerReading = Miles; this.setOdometer = function(newMiles) { this.odometerReading = newMiles; } } var car1 = new Car("blue", "1998", "Ford", 77777);
-
3.1.3 用 prototype 扩展和继承对象
- 扩展对象
function Person(personName) { this.name = personName; this.info = 'a'; this.showInfo = function() { alert(this.info); } } var person1 = new Person('adam'); var person2 = new Person('hehe'); Person.prototype.sayHello = function() { alert(this.name + 'say hello'); }
- 继承对象
function Pet() { this.animal = ""; } function Dog() { this.breed = ""; } Dog.prototype = new Pet();
3.1.4 封装
function a(b, c, d) { function kk(m, n) { return m + n; } }
3.2 对象进阶
3.2.1 类
-
新引入的 class 关键字和 constructor
function Pet() { this.animal = ""; this.setAnimal = function(newAnimal) { this.animal = newAnimal; } } class Pet { constructor(animal) { this.animal = animal; } setAnimal(newAnimal) { this.animal = newAnimal; } }
- 使用 getter 和 setter
- 下划线前缀防止被重复调用
class Pet { constructor(animal, name) { this.animal = animal; this.name = name; } get name() { return this._name; } set name(n) { n = n.charAt(0).toUpperCase() + n.slice(1).toLowerCase(); this._name = n; } }
- Symbol
-
创建的 Symbol 一定是唯一的传的参数只是说明
var myname = Symbol('nickname'); myCat[myname] = 'heheda';
-
3.2.2 对象继承
3.2.3 使用功能检测
if (document.getElementById) { // do something } else { // other }
-
typeof
if (typeof document.getElementById == 'function') { // do something } else { // other }
- typeof 的返回值 “number” “string” “boolean” “object” null undefined
3.3 DOM 脚本编程
3.3.1 DOM 节点
- 节点类型
- nodeType 每种节点类型都有一个关联的数值,保存在属性 nodeType
- 元素
- 属性
- 文本
- CDATA 区域
- 实体引用
- 实体
- 执行指令
- HTML 注释
- 文档
- 文档类型(DTD)
- 文档片段
- 标签
-
childNodes 属性
function countListItems() { var olElement = document.getElementById("toDoList"); var count = 0; for (var i = 0; i < olElement.childNodes.length; i++) { if (olElement.chiodNodes[i].nodeType == 1) count++; } } window.onload = countListItems;
- firstChild lastChild myElement.childNodes[0] myElement.childNodes[myElement.childNodes.length - 1];
- parentNode 属性
- nextSibling previousSibling
- nodeType 每种节点类型都有一个关联的数值,保存在属性 nodeType
- 使用 nodeValue
- 使用 nodeName
3.3.2 用 getElementsByTagName() 选择元素
- 基本用法 var myDics = document.getElementsByTagName(“div”);
- document.getElementsByClassName()
3.3.3 读取元素的属性
var myNode = document.getElementById("id1"); alert(myode.getAttribute("title"));
3.3.4 Mozilla 的 DOM 查看器
- 创建新节点
- 创建步骤
- 创建新节点
- createElement() var newDiv = document.createElement(“div”);
- createTextNode() var newTextNode = document.createTextNode(“heheda”);
- cloneNode() var myDiv = document.getElementById(“id1”); var newDiv = myDiv.cloneNode(true) true 代表会复制子节点一般需要修改 id 值
- 添加到 DOM 树
- 创建新节点
- 创建步骤
- 操作子节点
- appendChild() var newText = document.createTextNode(“heheda”); var myDiv = document.getElementById(“id1”); myDiv.appendChild(newText);
- insertBefore() var newPara = document.createElement(“p”); var myDiv = document.getElementById(“id1”); var para2 = document.getElementById(“para2”); myDiv.insertBefore(newPara, para2);
- para.replaceChild(new, old)
-
removeChild()
var myDiv = document.getElementById("id1"); var myPara = document.getElementById("para2"); var removedItem = myDiv.removeChild(myPara); alert(removedItem.getAttribute("id"));
- 编辑元素属性
var myPara = document.getElementById("para1"); myPara.setAttribute("title", "opening paragraph");
- 动态加载 JavaScript 文件
var scr = document.createElement("script"); scr.setAttribute("src", "newScript.js"); document.head.appendChild(scr);
3.4 JSON 简介
3.4.1 JSON 是什么
- 使用 JSON 表示法时,对象可以方便的转换为字符串来进行存储和转换
- JSON 的真正优雅之处在于对象在 JSON 里以普通 JS 代码表示,因此可以利用 JS “自动” 解析功能
3.4.2 访问 JSON 数据
- eval 函数参数:
- 表达式
- 表达式字符串
- 字符串,其中是括号包含的 json
var x = eval(1*2); eval("a=1;b=2;document.write(a+b);"); var user = '{"user":"admin", "location": "spain"}'; var myObject = eval('(' + user + ')');
3.4.3 JSON 的数据序列化
3.4.4 JSON 数据类型
- 参数部分的规则
- 不能是 JS 保留的关键字
- 不能数字开头
- 特殊字符只能有下划线和美元符号
- 值可以是以下数据类型
- 数值
- 字符串
- 布尔值
- 数组
- 对象
- null
3.4.5 模拟关联数组
- 在 JS 中,object[“property”] 和 object.property 是对等的
var conference = {"a": "1", "b": "2"}; alert(conference["a"]); alert(conference.a);
3.4.6 使用 JSON 创建对象
- 用方括号表示数组 var categories = [“news”, “sports”];
3.4.7 JSON 安全性
- eval() 能执行任何 JS 命令,对于来源不明的 JSON 数据可能存在安全问题,安全的办法是使用内置 JSON 解析器,它只识别 JSON 文本而不会执行脚本命令
4 用 JavaScript 操作 Web 界面
4.1 HTML 与 JavaScript 编程
4.1.1 HTML5 的新标签
- section
- header
- footer
- nav
- article
- aside
- figure
- figcaption
- summary
4.1.2 一些重要的新元素
- 用<video> 回放视频
- 用 canPlayType() 测试可用的格式
- media.canPlayType(“video/webm”);
- 控制回放
var myVideo = document.getElementById("vid1").play(); var myVideo = document.getElementById("vid1").pause();
- 用<audio> 标签播放声音
var soundElement = document.createElement('audio'); soundElement.setAttibute('src', 'sound.ogg'); soundElement.play(); soundElement.currentTime = 12;
- 用<canvas> 在页面上绘图
4.1.3 拖放
4.1.4 本地存储
-
两个对象 localStorage sessionStorage
if (typeof(Storage) != "undefined") { localStorage.setItem("key", "value"); localStorage["key"] = "value"; alert(localStorage.getItem("key")); alert(localStorage["key"]); }
4.2 JavaScript 和 CSS
4.2.2 DOM 的 style 属性
4.2.3 用 className 访问类
4.3 CSS3 简介
5 与 JavaScript 工具相关的高级技术
5.1 读取和写入 cookie
5.1.2 使用 document.cookie 属性
5.1.3 cookie 组成
- cookieName 和 cookieValue
- domain 用于指明 cookie 属于哪个域,如果为 a.com ,则 b.a.com 可以访问这个 cookie
- path 指定可以使用 cookie 的路径
- secure 表明浏览器把 cookie 发给服务器时,是否要使用 SSL 标准
- expires 以 UTC 标准的过期时间
5.1.4 编写 cookie
var cookieDate = new Date ( 2018, 05, 15 ); var user = "heheda"; document.cookie = "username=" + escape(user) + ";expires=" + cookieDate.toUTCString();
5.1.5 编写一个函数来写 cookie
5.1.6 读取 cookie
5.1.7 删除 cookie
- 把一个 cookie 的失效日期设置为今天之前即可
5.1.8 在一个 cookie 里设置多个值
5.2 用正则表达式匹配模式
5.2.1 创建正则表达式
- JS 里两种生成正则表达式的方法
- 使用正则表达式字符串字面量
-
var myRegExp = FooBar;
var myRepExp = /FooBar/; if (document.getElementById("txt").value.search(myRegExp) == -1) { alert("not found"); } else { alert("The string occurs"); }
- 正则表达式修饰符
i 不区分大小写 g 全局匹配,而不是找到第一个匹配就停止 m 多行匹配 var aa = /stupid/gi;
- 方括号[]指定范围
- 处理特殊字符的快捷方式,元字符 \w 等
- 正则表达式限定符 + 重复次数等
-
- 使用 JS 的 RegExp 对象
var myPattern = new RegExp("Foobar"); var result = /boy/.exec("heheda"); console.log(result[0]); myPattern.test("this is a test"); var result = myPattern.exec(myString);
- 对正则表达式使用字符串方法
-
match search replace split
var myString = "heheda dada"; var outString = myString.match(/\d+/g); var myString = "1 ;2 3;4 5"; var outString = myString.split(/\s*;\s*/); myString.replace(/stupid/ig, "cupid");
-
用一个函数作为 replace() 的参数
function CtoF(match) { return ((match * 9) / 5) + 32; } var myString = "for 1 and 5"; myString = myString.replace(/\d+/g, CtoF);
-
5.3 理解并使用闭包
5.3.1 回顾作用域的相关知识
5.3.2 从一个函数返回另一个函数
5.3.3 实现闭包
- 闭包是访问父作用域的一个函数,即便是在该作用域已经结束之后.
- 传递参数
function sayHi(visitor) { let msg = visitor + ' says: hello world!'; return function logMessage() { console.log(msg); } }
- 编辑一个闭包变量
function sayHi(visitor) { let msg = visitor + ' says: '; return function logMessage(extra) { msg = msg + extra; console.log(msg); } } var helloPhil = sayHi("Phil"); var helloSue = sayHi("Sue");
- 闭包和变量
- 闭包也允许将一些数据和操作这些数据的函数关联起来
function sayHi(visitor) { let msg = visitor + ' says: hello world'; return function logMessage() { console.log(msg); } } var helloPhil = sayHi("Phil"); helloPhil()
- 对象提供了灵活性,但是到处都可以修改,容易出现错误.
5.4 用模块组织代码
5.4.2 模块基础知识
- 一个文件一个模块,模块中的内容对外部不可见.
- 模块是通过 CORS 跨源资源共享来获取的
5.4.3 导出
function fun1(x) { alert(x); } export func1;
- 一个简单的示例模块
function convertCtoF(c) { return (c*1.8) + 32; } function convertFtoC(c) { return (f-32) / 1.8; } export {convertCtoF, convertFtoC} export var a = "something"; export function func1() {console.log("hello");};
- 如何在导出时重命名
export var distance = arr[1]; export {arr as routeProperties };
- 具名的和默认的导出
function mmToInches(d) { return d/25.4; } export default mmToInches;
5.4.4 导入
import {convertCtoF, convertFtoC} from './tempConvert.js';
6 专业技能
6.1 良好的编程习惯
6.1.1 避免过度使用 JS
6.1.2 编写易读和易维护的代码
6.1.3 平稳退化
6.1.6 功能检测
6.2 调试代码
6.3 继续深入学习
6.3.1 为什么要使用库
6.3.2 库能做什么
- 一般库的功能
- 封装 DOM 方法
- 动画
- 拖放
- Ajax
6.3.3 一些常见的库和框架
6.3.4 jQuery 入门
- 在页面里引用 jQuery
- 本地下载 <script src=“jquery-3.3.1.js”></script>
- 远程 <script src=“https://ajax.googleapis.com/ajax/libs/jquery/3.3..1/jquery.min.js”></script>
- jQuery 的$(document).ready 处理器
-
类似于 window.onload
$(document).ready(function() { // code });
-
- 选择页面元素
- $(“”) 即可选择 HTML 元素 $(“span”) $(“#elem”) //id $(“.classname”) $(“div#elem”) $(“ul li a.menu”) / 类为 menu,且嵌套在列表项里的锚点 $(“p > span”) / p 的直接子元素 span $(“input[type=password]”) $(“p:first”) $(“p:even”) // 全部偶数段落 $(“:header”) //标题元素 $(“:button”) $(“:radio”) $(“:checkbox”) $(“:checked”)
- 操作 HTML 内容
-
html() 类似于 innerHTML
var htmlContent = $("#elem").html(); $("#elem").html("<p>here </p>");
-
text() 只是获取文本内容
var textContent = $("#elem").text() $("#elem").append("<p>hehe </p>");
-
attr()
var title = $("#elem").attr("title"); $("elem").attr("title", "new title");
-
- 显示和隐藏元素
- JS 中 document.getElementById(“elem”).style.visibility = “visible”;
-
show()
$("div").show(); $("#elem").show("fast", function() { // 操作 });
-
hide()
$("#elem").hide("slow", function() { // 隐藏之后的操作 });
-
toggle()
$("#elem").toggle(1000, function() { // xx });
- 命令链
-
jQuery 大多数方法都返回一个 jQuery 对象
$("#elem").fadeOut().fadeIn(); $("#elem").text("Hello ").fadeOut().fadeIn();
-
- 处理事件
-
常用方法
$("a").click(function() { // }); function hello() { alert("hello"); } $("a").click(hello); $("a").on("click", hello);
- 常见事件 blur focus hover keypress change mousemove resize scroll submit select
-
6.3.6 Ajax 简介
- Ajax 入门
- XMLHttpRequest 对象
- XMLHttpRequest 能够建立与服务器的连接,发送 http 请求而不需要加载相应的页面
- 默认 xhr 只能对同域发起请求,除非服务端做了设置
- 创建 request 对象
- var request = new XMLHttpRequest();
- 方法和属性
- 属性 onreadystatechage readyState responseText responseXML status statusText
- 方法 abort() getAllResponseHeaders() getResponseHeader(x) open(’method’,’URL’,’a’) // a 默认为 true,表示异步 send(content) setRequestHeader(’x’,’y’)
- 与服务器通信
- 在服务器端发生了什么
- 处理服务器响应
- 还有更容易的方法,不是吗?
6.3.7 用 jQuery 实现 Ajax
-
load()
$(function() { $("#elem").load("newContent.html"); }); $(function() { $("#elem").load("newContent.html #info"); });
-
get() post()
$.get("serverScript.php", {param1: "value1", param2: "value2"}, function(data) { alert("server response: " + data); });
- ajax()
- 对表单数据进行序列化 var formdata = $(’#form1’).serialize();
Created: 2019-11-13 Wed 22:40