1. JavaScript 代码是放在<script> ……</script> 标签里,而包含 JavaScript 代码的 script 标签,我们可以放在 <body> ……</body>标签里,也可以放在<head> ……</head>标签里。
<script>js代码</script>
可以引用执行js文件
<script src="test.js"> </script>
2.变量声明
通过var关键字或者直接写
变量类型
- Number:你可以在变量中存储数字,不论这些数字是像 10(整数)这样,或者像 3.1415926(浮点数)。
var x1 = 10;
var x2 = 3.1415926;
- String:存储字符
- Boolean:布尔类型的值有两种:true 和 false。
- Array:数组是一个单个对象,其中包含很多值,方括号括起来,并用逗号分隔。
var myNameArray = ['Tom', 'Bob', 'Jim'];
var myNumberArray = [10,15,20];
- Object:对象类型。
3.数组声明,for..in..循环
var myarray = new Array(1,2,3,4,5); // 创建数组同时赋值
//or
var myarray = [1,2,3,4,5]; //直接输入一个数组(称 “字面量数组”)
数组内置了非常多的方法,每个新建数组进可以看做一个数组对象,直接使用方法即可
4.==/=== null/undefined
== 是相等操作符,比较值是否相等,如果相等输出为 true,否则为 false。=== 是全等操作符,比较值和类型是否都相等,如果都相等输出为 true,否则为 false。
null 和 undefined 都表示无.undefined 表示所有没有赋值变量的默认值,而 null 则表示一个变量不再指向任何对象地址。
5.常用类型转换方法
Number()可以把任意值转换成数值,如果要转换的字符串中有一个不是数值的字符,返回 NaN(not a number)
parseInt() 把字符串转换成整数。parseInt()可以传递两个参数,第一个参数是要转换的字符串,第二个参数是要转换的进制。
parseFloat()把字符串转换成浮点数。parseFloat不支持第二个参数,只能解析 10 进制数,如果解析的内容里只有整数,解析成整数.
String() 将任意值转换成字符串
6.创建函数
函数声明创建函数
function functionName(parameters) {
//执行的代码
}
函数表达式创建函数
var functionName = function (parameters){
//执行的代码
}
两者的区别在于:JavaScript解析器首先会把当前作用域的函数声明提前到整个作用域的最前面。
而函数表达式只有在执行到那一步时才进行声明
在 JavaScript 中没有重载
function f(a,b) {
return a + b;
}
function f(a,b,c) {
return a + b + c;
}
var result = f(5,6);
result;// returns NaN
上述代码中三个参数的 f 把两个参数的 f 覆盖,调用的是三个参数的 f,最后执行结果为 NaN。
如果函数中没有 return 语句,那么函数默认的返回值是:undefined。
匿名函数
匿名函数就是没有命名的函数,一般用在绑定事件的时候。语法为:
function(){
}
例子:
var myButton = document.querySelector('button');
myButton.onclick = function() {
alert('hello');
}
将匿名函数分配为变量的值,也就是我们前面所讲的函数表达式创建函数。一般来说,创建功能,我们使用函数声明来创建函数。使用匿名函数来运行负载的代码以响应事件触发(如点击按钮) ,使用事件处理程序。
7.常用内置对象
Array 对象
- Array 对象的常用属性:length。获取数组的长度。
- Array 对象的常用方法:
- concat()方法用于连接两个或多个数组,并返回结果
- join() 方法,将数组转换成字符串。
- pop() 方法,删除并返回数组的最后一个元素。
- push() 方法,向数组的末尾添加一个或更多元素,并返回新的长度。
- reverse() 方法,颠倒数组的顺序
- shift() 方法,删除并返回数组的第一个元素。
- unshift() 方法,向数组的开头添加一个或更多元素,并返回新的长度。
- slice() 方法,从某个已有的数组返回选定的元素。语法为:
-
arrayObject.slice(start,end); //strat 值是必需的,规定从何处开始选取。 //end 值可选,规定从何处结束选取,如果没有设置,默认为从 start 开始选取到数组后面的所有元素。
- splice() 方法,删除或替换当前数组的某些项目
arrayObject.splice(start,deleteCount,options)
// start 值是必需的,规定删除或替换项目的位置
// deleteCount 值是必需的,规定要删除的项目数量,如果设置为 0,则不会删除项目。
// options 值是可选的,规定要替换的新项目
// 和 slice() 方法不同的是 splice() 方法会修改数组。
var a = [1,2,3,4,5,6];
a.splice(2,2,"abc");
a; // 最终 a 数组变成了[1, 2, "abc", 5, 6]
- sort() 方法,将数组进行排序。
- toString() 方法,把数组转换为字符串,并返回结果。
String 对象
- charAt() 方法,获取指定位置处字符。语法为:
stringObject.charAt(index);
//字符串中第一个字符的下标是 0。如果参数 index 不在 0 与 string.length 之间,该方法将返回一个空字符串。
- charCodeAt() 方法,获取指定位置处字符的 Unicode 编码。语法为:
stringObject.charCodeAt(index);
//字符串中第一个字符的下标是 0。如果 index 是负数,或大于等于字符串的长度,则 charCodeAt() 返回 NaN。
- concat() 方法,连接字符串,等效于 “+”,“+” 更常用。与数组中的 concat() 方法相似。
- slice() 方法,提取字符串的片断,并在新的字符串中返回被提取的部分(字符串章节有详细介绍,这里不过多的赘述,下面的类似情况同样处理)。
- indexOf() 方法,检索字符串。
- toString() 方法,返回字符串。
- toLowerCase() 方法,把字符串转换为小写。
- toUpperCase() 方法,把字符串转换为大写。
- replace() 方法,替换字符串中的某部分。
- split() 方法,把字符串分割为字符串数组。
Date 对象
- Date():返回当日的日期和时间。(输出是中国标准时间)
- getDate():从 Date 对象返回一个月中的某一天 (1 ~ 31)。
- getDay():从 Date 对象返回一周中的某一天 (0 ~ 6)。
- getMonth():从 Date 对象返回月份 (0 ~ 11)。
- getFullYear():从 Date 对象以四位数字返回年份。
- getHours():返回 Date 对象的小时 (0 ~ 23)。
- getMinutes():返回 Date 对象的分钟 (0 ~ 59)。
- getSeconds():返回 Date 对象的秒数 (0 ~ 59)。
- getMilliseconds():返回 Date 对象的毫秒(0 ~ 999)。
Math 对象
- E :返回常数 e (2.718281828...)。
- LN2 :返回 2 的自然对数 (ln 2)。
- LN10 :返回 10 的自然对数 (ln 10)。
- LOG2E :返回以 2 为底的 e 的对数 (log2e)。
- LOG10E :返回以 10 为底的 e 的对数 (log10e)。
- PI :返回π(3.1415926535...)。
- SQRT1_2 :返回 1/2 的平方根。
- SQRT2 :返回 2 的平方根。
- abs(x) :返回 x 的绝对值。
- round(x) :返回 x 四舍五入后的值。
- sqrt(x) :返回 x 的平方根。
- ceil(x) :返回大于等于 x 的最小整数。
- floor(x) :返回小于等于 x 的最大整数。
- sin(x) :返回 x 的正弦。
- cos(x) :返回 x 的余弦。
- tan(x) :返回 x 的正切。
- acos(x) :返回 x 的反余弦值(余弦值等于 x 的角度),用弧度表示。
- asin(x) :返回 x 的反正弦值。
- atan(x) :返回 x 的反正切值。
- exp(x) :返回 e 的 x 次幂 (e^x)。
- pow(n, m) :返回 n 的 m 次幂 (nm)。
- log(x) :返回 x 的自然对数 (ln x)。
- max(a, b) :返回 a, b 中较大的数。
- min(a, b) :返回 a, b 中较小的数。
- random() :返回大于 0 小于 1 的一个随机数。
8.创建对象
两种基本方式构建对象
通过对象字面量来创建
var student = {
name: 'zhangsan',
age: 18,
gender : 'male',
sayHi: function () {
console.log("hi,my name is "+this.name);
}
};
通过 new Object() 创建对象
var student = new Object();
student.name = 'zhangsan',
student.age = 18,
student.gender = 'male',
student.sayHi = function () {
console.log("hi,my name is "+this.name);
}
为避免冗余,通过函数封装来创建对象
通过工厂函数创建对象
function createStudent(name, age, gender) {
var student = new Object();
student.name = name;
student.age = age;
student.gender = gender;
student.sayHi = function(){
console.log("hi,my name is "+this.name);
}
return student;
}
var s1 = createStudent('zhangsan', 18, 'male');
自定义构造函数
function Student(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayHi = function(){
console.log("hi,my name is "+this.name);
}
}
var s1 = new Student('zhangsan', 18, 'male');
使用 delete 删除对象的属性。delete student.name;
9.Web API
Web API 是浏览器提供的一套操作浏览器功能和页面元素的 API(BOM 和 DOM)。
BOM
浏览器对象模型(BOM)指的是由 Web 浏览器暴露的所有对象组成的表示模型。BOM 与 DOM 不同,其既没有标准的实现,也没有严格的定义, 所以浏览器厂商可以自由地实现 BOM。
作为显示文档的窗口, 浏览器程序将其视为对象的分层集合。当浏览器分析文档时, 它将创建一个对象的集合, 以定义文档, 并详细说明它应如何显示。浏览器创建的对象称为文档对象。它是浏览器使用的更大的对象集合的一部分。此浏览器对象集合统称为浏览器对象模型或 BOM。
BOM 层次结构的顶层是窗口对象, 它包含有关显示文档的窗口的信息。某些窗口对象本身就是描述文档和相关信息的对象。
window 是浏览器的顶级对象
,当调用 window 下的属性和方法时,可以省略 window。
对话框
- alert():显示带有一段消息和一个确认按钮的警告框。
- prompt():显示可提示用户输入的对话框。
- confirm():显示带有一段消息以及确认按钮和取消按钮的对话框。
页面加载事件
- onload
window.onload = function () {
// 当页面加载完成执行
// 当页面完全加载所有内容(包括图像、脚本文件、CSS 文件等)执行
}
- onunload
window.onunload = function () {
// 当用户退出页面时执行
}
浏览器尺寸
var width = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
var height = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
上述代码可以获取所有浏览器的宽高((不包括工具栏/滚动条))。
定时器
- setTimeout() 方法在指定的毫秒数到达之后执行指定的函数,只执行一次。clearTimeout() 方法取消由 setTimeout() 方法设置的 timeout。
// 创建一个定时器,2000毫秒后执行,返回定时器的标示
var timerId = setTimeout(function () {
console.log('Hello');
}, 2000);
// 取消定时器的执行
clearTimeout(timerId);
- setInterval() 方法设置定时调用的函数也就是可以按照给定的时间(单位毫秒)周期调用函数,clearInterval() 方法取消由setInterval() 方法设置的 timeout。
// 创建一个定时器,每隔2秒调用一次
var timerId = setInterval(function () {
var date = new Date();
console.log(date.toLocaleTimeString());
}, 2000);
// 取消定时器的执行
clearInterval(timerId);
DOM
文档对象模型(Document Object Model,简称DOM),是 W3C 组织推荐的处理可扩展标志语言的标准编程接口。DOM 定义了访问 HTML 和 XML 文档的标准。我们这里主要学习 HTML DOM。DOM 可以把 HTML 看做是文档树,通过 DOM 提供的 API 可以对树上的节点进行操作。
在 JavaScript 中,使用 document.write() 可用于直接向 HTML 输出流写内容。
document.write('新设置的内容<p>标签也可以生成</p>');
使用 innerHTML 属性改变 HTML 内容。
document.getElementById("p1").innerHTML = "Hello ";//通过.getElementById方法获取元素标签,通过innerHTML修改内置html内容,得到的元素标签相当于对象,元素标签的属性可以看做是对象的属性,可进行修改
- <img id="image" src="https://www.baidu.com/img/bd_logo1.png">
- <script>
- document.getElementById("image").src = "xxx";
- </script>
进一步的,如果标签属性也是对象,也可直接修改
- <p id="syl" style="color: red;">x</p>
- <script>
- document.getElementById("syl").style.color = "green";
- </script>
根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:整个文档就是一个文档节点。而每一个 HMTL 标签都是一个元素节点。HTML 标签中的文本则是文本节点。HTML 标签的属性是属性节点。一切都是节点。
获取节点
通过 ID 找到 HTML 元素:使用方法 getElementById() 通过元素的 ID 而选取元素
通过标签名找到 HTML 元素:使用方法 getElementsByTagName() 来选取元素,如果有多个同类型标签,那么我们可以通过下标来确认
通过类名来找到 HTML 元素:使用方法 getElementsByClassName() 通过元素的类名来选取元素
例:document.getElementsByClassName("name"); // 返回包含 class="name" 的所有元素的一个列表。
DOM 的节点并不是孤立的,我们从 dom 树中也可以看出,节点与节点之间存在着相对的关系,就如同一个家族一样,有父辈,有兄弟,有儿子等等。下面我们来看一下都有哪些节点:
父节点 | 兄弟节点 | 子节点 | 所有子节点 |
---|---|---|---|
parentNode | nextSibling | firstChild | childNodes |
nextElementSibling | firstElementChild | children | |
previousSibling | lastChild | ||
previousElementSibling | lastElementChild |
例子:
<html>
<head>
<title>DOM 节点演示</title>
</head>
<body>
<h1>我是h1标签</h1>
<p>我是p标签</p>
</body>
</html>
上面的例子中:
- <html>节点没有父节点,它是根节点。
- <head> 和 <body> 的父节点是 <html> 节点
- 文本节点 "我是p标签"的父节点是 <p> 节点
- <html>节点有两个子节点: <head> 和 <body>
- <h1>节点和<p>节点是兄弟节点,同时也是<body>的子节点
需要注意以下几点:
- childNodes:它是标准属性,它返回指定元素的子元素集合,包括 HTML 节点,所有属性,文本节点
- children:非标准属性,它返回指定元素的子元素集合。但它只返回 HTML 节点,甚至不返回文本节点。
- nextSibling 和 previousSibling 获取的是节点,获取元素对应的属性是 nextElementSibling 和 previousElementSibling。
- nextElementSibling 和 previousElementSibling 有兼容性问题,IE9 以后才支持。
DOM 节点的操作
-
创建节点
-
创建元素节点:使用 createElement() 方法。比如:
var par = document.createElement("p");
-
创建属性节点:使用 createAttribute() 方法。
-
创建文本节点:使用 createTextNode() 方法。
-
-
插入子节点
- appendChild () 方法向节点添加最后一个子节点。
- insertBefore (插入的新的子节点,指定的子节点) 方法在指定的子节点前面插入新的子节点。如果第二个参数没写或者为 null,则默认插入到后面。
-
删除节点:使用 removeChild() 方法。写法为:
父节点.removeChild(子节点);
node.parentNode.removeChild(node); //如果不知道父节点是什么,可以这样写
- 替换子节点:使用 replaceChild() 方法。语法为:
node.replaceChild(newnode,oldnode);
-
设置节点的属性:
- 获取:getAttribute(名称)
- 设置:setAttribute(名称, 值)
- 删除:removeAttribute(名称)
DOM 事件
事件三要素
事件由:事件源 + 事件类型 + 事件处理程序组成。
- 事件源:触发事件的元素。
- 事件类型:事件的触发方式(比如鼠标点击或键盘点击)。
- 事件处理程序:事件触发后要执行的代码(函数形式,匿名函数)。
常用的事件
事件名 | 说明 |
---|---|
onclick | 鼠标单击 |
ondblclick | 鼠标双击 |
onkeyup | 按下并释放键盘上的一个键时触发 |
onchange | 文本内容或下拉菜单中的选项发生改变 |
onfocus | 获得焦点,表示文本框等获得鼠标光标。 |
onblur | 失去焦点,表示文本框等失去鼠标光标。 |
onmouseover | 鼠标悬停,即鼠标停留在图片等的上方 |
onmouseout | 鼠标移出,即离开图片等所在的区域 |
onload | 网页文档加载事件 |
onunload | 关闭网页时 |
onsubmit | 表单提交事件 |
onreset | 重置表单时 |
例子 1 :鼠标单击事件:
<p onclick="this.innerHTML='我爱学习,身体好好!'">请点击该文本</p>
例子2 :鼠标双击事件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1 ondblclick="changetext(this)">请点击该文本</h1>
<script>
function changetext(id) {
id.innerHTML = "我爱学习,身体棒棒!"
}
</script>
</body>
</html>
例子3 :鼠标移除悬停:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div onmouseover="mOver(this)" onmouseout="mOut(this)" style="background-color:deepskyblue;width:200px;height:100px;">把鼠标移到上面</div>
<script>
function mOver(obj) {
obj.innerHTML = "你把鼠标移到了上面 ";
}
function mOut(obj) {
obj.innerHTML = "你把鼠标移开了";
}
</script>
</body>
</html>
10.值类型与引用类型
值类型又叫基本数据类型,在 JavaScript 中值类型有以下五种:
- 数值类型
- 布尔类型
- undefined
- null
- 字符串
值类型存储在栈(stack)中,它们的值直接存储在变量访问的位置。
引用类型又叫复合数据类型,在 JavaScript 中引用类型有以下三种:
- 对象
- 数组
- 函数
引用类型存储在堆中,也就是说存储在变量处的值是一个指针,指向存储对象的内存处。
11.异常
我们使用 try-catch 语句捕获异常,语法为:
try{
//这里写可能出现异常的代码
}catch(err){
//在这里写,出现异常后的处理代码
}
通过 throw 语句,我们可以创建自定义错误。throw 语句常常和 try catch 语句一起使用。
throw xxx//xxx可以是String或其他各种类型
12.原型:prototype
在 JavaScript 中,每一个函数都有一个 prototype 属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承,其实就是超类Object。
函数是一个对象,其原型prototype为Object,有一个constructor属性,指向其构造函数本身
所有的对象都有原型,而原型也是对象,也就是说原型也有原型,那么如此下去,也就组成了我们的原型链。
属性搜索原则,也就是属性的查找顺序,在访问对象的成员的时候,会遵循以下原则:
- 首先从对象实例本身开始找,如果找到了这个属性或者方法,则返回。
- 如果对象实例本身没有找到,就从它的原型中去找,如果找到了,则返回。
- 如果对象实例的原型中也没找到,则从它的原型的原型中去找,如果找到了,则返回。
- 一直按着原型链查找下去,找到就返回,如果在原型链的末端还没有找到的话,那么如果查找的是属性则返回 undefined,如果查找的是方法则返回 xxx is not a function。
如果需要在对象中添加静态方法,则只需重写该对象的原型即可,在原型中添加相应属性,对于构造函数而言,注意要添加constructor:对象,使constructor指向原对象。
function Student(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
Student.prototype = {
constructor: Student, //手动将 constructor 指向正确的构造函数
hobby:"study",
sayHi:function(){
console.log("hi");
}
}
var s1 = new Student("wangwu",18,"male");
console.log(Student.prototype.constructor === Student);//结果为 true
Object也有原型,包含一些超类方法
13.更改指针this
call() 方法调用一个函数, 其具有一个指定的 this 值和分别地提供的参数(参数的列表)。语法为:
fun.call(thisArg, arg1, arg2, ...)
- thisArg 指的是在 fun 函数中指定的 this 的值。如果指定了 null 或者 undefined 则内部 this 指向 window,同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。是一个可选项。
- arg1, arg2, ...指定的参数列表。也是可选项。
函数调用call(thisArg)会将该函数内的this替换为thisArg,将函数参数依次替换为arg1,arg2...
function Father(name, age) {
this.name = name;
this.age = age;
}
function Son(name, age) {
Father.call(this, name, age);
this.hobby = 'study';
}
var S1 = new Son('zhangsan', 18);
S1; // Son {name: "zhangsan", age: 18, hobby: "study"}
apply() 方法与 call() 方法类似,唯一的区别是 call() 方法接受的是参数,apply() 方法接受的是数组。语法为:
fun.apply(thisArg, [argsArray])
bind() 方法返回一个新的函数(称为绑定函数),在调用时设置 this 关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。
看一个例子:
this.num = 6;
var test = {
num: 66,
getNum: function() { return this.num; }
};
test.getNum(); // 返回 66
var newTest = test.getNum;
newTest(); // 返回 6, 在这种情况下,"this"指向全局作用域
// 创建一个新函数,将"this"绑定到 test 对象
var bindgetNum = newTest.bind(test);
bindgetNum(); // 返回 66
14.作用域
块级作用域
在 JavaScript 中是没有块级作用域的。比如:
{
var num = 123;
{
console.log( num );
}
}
console.log( num );
上面的例子并不会报错,而是打印两次 123。
函数作用域
JavaScript 的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的,不涉及赋值。来看个例子:
function test() {
var num = 123;
console.log(num);
if(2 == 3) {
var k = 5;
for(var i = 0; i < 10; i++) {
}
console.log(i);
}
console.log(k); //不会报错,而是显示undefined
}
全局作用域
全局作用域也就是说什么地方都能够访问到。比如我们不用 var 关键字,直接声明变量的话,那个变量就是全局变量,它的作用域就是全局作用域。使用 windows 全局对象来声明,全局对象的属性也是全局变量。另外在所有的函数外部用 var 声明的变量也是全局变量
变量名提升
JavaScript 是解释型的语言,但是它并不是真的在运行的时候完完全全的逐句的往下解析执行。
javaScript 引擎在对 JavaScript 代码进行解释执行之前,会对 JavaScript 代码进行预解析,在预解析阶段,会将以关键字 var 和 function 开头的语句块提前进行处理:当变量和函数的声明处在作用域比较靠后的位置的时候,变量和函数的声明会被提升到作用域的开头。也就是说上面的代码,我们可以理解为:
看看变量声明的例子:
console.log(num);
var num = 10;
结果可能有些出人意料,但是我们这里说的是声明的提升,也就是说上面的代码,我们可以理解为:
var num; //这里是声明
console.log(num);//变量声明之后并未有初始化和赋值操作,所以这里是 undefined
num = 10;
下面再来看几个复杂一点的例子。
函数同名的时候:
func();
function func(){
console.log("Hello syl");
}
func();
function func(){
console.log("hi syl");
}
上面代码相当于:
function func(){
console.log("Hello syl");
}
function func(){
console.log("hi syl");
}
func();
func();
函数变量同名的时候:
console.log(foo);
function foo(){}
var foo = 6;
当出现变量声明和函数同名的时候,只会对函数声明进行提升,变量会被忽略。所以上面的代码相当于:
function foo(){};
console.log(foo);
foo = 6;
我们再来看一种:
var num = 1;
function num () {
alert( num );
}
num();
上面的代码相当于:
function num(){
alert(num);
}
num = 1;
num();
var num = 3;
function foo(){
console.log(num);
var num = 4;
console.log(num);
}
foo();
上面的代码相当于:
var num = 3;
function foo(){
var num; // 在函数顶部声明了局部变量,覆盖了函数体外同名的全局变量
console.log(num); // 变量存在,但是它的值为 undefined
num = 4; // 将其初始化赋值。
console.log(num); //打印我们期望的值 4
}
15.函数技巧
闭包是指函数可以使用函数之外定义的变量。
简单的闭包
在 JavaScript 中,使用全局变量是一个简单的闭包实例。比如:
var num = 3;
function foo(){
console.log(num);
}
foo(); //打印 3
复杂闭包
指函数内部的值如何被外部访问,这个通过return 返回数值即可
函数参数arguments
在函数代码中,使用特殊对象 arguments,即函数参数数组,无需明确指出参数名,我们就能访问它们。第一个参数是 arguments[0],第二个参数是 arguments[1],以此类推。比如:
function foo() {
console.log(arguments[0]);
console.log(arguments[1]);
}
foo(2,3);//打印 2 3
还可以用 arguments 对象检测函数的参数个数,引用属性 arguments.length 即可。