导语
HTML定义网页内容,CSS定义网页布局,JavaScript定义网页行为。
javascript是浏览器客户端脚本语言,代码放在HTML文件的<head></head>
或<body></body>
中,需要用<script></script>
标签包含。引用外部Javascript文件(以.js
结尾,且脚本文件中不包含<script></script>
标签),需要在<script>
标签的src属性中指定脚本位置。
基本语法
Javascript运算符:+、-、*、/、==(类型被忽略,只比较值,比如10 == “10”返回true)、===(值和类型都相等)、!=、!==(类型不相等或值不相等)、<、>、<条件>?<条件为true执行> :<条件为false执行> 。
单行注释采用//,多行注释采用/**/。
输出
- window.alert():弹出警告框。
- document.write():将内容写到HTML文档。如果在HTML文档加载完成后调用此方法,输出会覆盖整个页面。
- innerHTML:写入到HTML元素。
- console.log():写入到浏览器控制台。
字面量
- 数字字面量:如
3.14
、1.23e5
。 - 字符串字面量:单引号或双引号包含,如
'str'
,"str1"
。 - 表达式字面量:如
5 + 3
。 - 对象字面量:如
{name: "mars loo"}
。 - 函数字面量:如
function mySum(a, b) { return a + b;}
。 - 数组字面量:如
[1, 2]
。
变量
有5种数据类型:string、number、boolean(取值true或false)、object、function,3种对象类型:Object、Date、Array,两个不包含任何数据的类型:null(清空变量)、undifined(变量未定义)。Javascript变量均可作为对象使用。
typeof
可以获取变量的类型,如typeof null
返回object,typeof undefined
返回undefined。
使用var定义变量,变量名常用驼峰命名方式,对大小写敏感,采用unicode字符集。如果一个变量声明时未赋值,它的值将会是undefined。如果重新声明一个已经赋值的变量却未提供初始值,则该变量的原本的值不会丢失:var b = 3; var b;
,变量b的值最终为3。
string
使用单引号或双引号包围的字符串,也可以用对象表示字符串,如:
- 1
- 2
- 3
- 1
- 2
- 3
输出:string object true false
。
特殊字符转义:
代码 | 输出 |
---|---|
\' | 单引号 |
\" | 双引号 |
\\ | 反斜杠 |
\n | 换行 |
\r | 回车 |
\t | 制表 |
\b | 退格 |
\f | 换页 |
string变量属性:
- length:字符串长度,如:
'string'.length
。 - prototype:定义字符串的属性和方法,如:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
输出为mars loo str-mars
。
- constructor:创建字符串属性的函数,
'str'.constructor
返回String()
。
string变量方法(x
表示一个string变量):
方法 | 描述 |
---|---|
x.charAt(n) | 位置n的字符,也可以使用x[n] |
x.charCodeAt(n) | 位置n的字符的Unicode值 |
x.concat(str) | 返回x与str拼接后的字符串 |
String.fromCharCode(n1, n2, …) | 返回Unicode值为n1, n2, …的字符拼接后的字符串 |
x.indexOf(str, start) | 从start位置开始,字符串str在x中首次出现的位置,没有找到返回-1 |
x.lastIndexOf(str, start) | 从start位置开始,字符串str在x中倒序第一次出现的位置,没有找到返回-1 |
String.localeCompare(str1, str2) | 返回str1、str2的语言本地排序结果 |
x.match(RegExp | str) | 在x中正则匹配或字符串匹配,将匹配到的字符串放在数组中返回,没有匹配返回null |
x.replace(RegExp | str, str | func) | 将x中找到的匹配替换为str,或者将找到的匹配替换为函数func作用后的返回值 |
x.search(RegExp | str) | 返回字符串x中查找到的第一个匹配的位置,没有找到匹配返回-1 |
x.slice(start, end) | 返回字符串x的切片,左闭右开 |
x.split(str | RegExp, n) | 将字符串x按照匹配分隔,返回分隔出的字符串组成的数组,参数n定义最多分隔成几份 |
x.substr(start, length) | 返回字符串x从位置start开始,长度为length的子字符串 |
x.substring(start, ?end) | 返回字符串x从位置start开始,到end为止的子字符串(左闭右开)。end是可选参数,如果不提供,默认到字符串x的结尾 |
x.toUpperCase() | 将字符串x中所有字符转换成大写后返回 |
x.toLowerCase() | 将字符串x中所有字符转换成小写后返回 |
x.trim() | 去除字符串x两端的空白后返回新串 |
Array
Javascript中,同一数组可以存储不同类型的变量。定义数组有三种形式:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
typeof 数组名
返回object。访问一个不存在的位置的数组元素,返回undefined。
数组只能以数字作为索引,如果使用字符串作为索引,则数组自动转换为对象。
Array类型变量属性:
- length属性:数组长度。
- constructor属性:可以用来判断变量类型,比如判断对象是否为数组:
undefined和null
undefined == null
:结果为true
undefined === null
:结果为false
检查对象是否存在:先检查是否是undefined,再检查是否是null,typeof myObj !== "undefined" && myObj !== null
。
对象
对象寻址有两种方式:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
对象访问自身变量的方法:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
function
把函数当做一个属性访问的话,会返回函数本身:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
效果是在网页上显示函数的定义,在浏览器控制台输出函数的类型及位置信息:
number
NaN(非数值)的类型是number,使用isNaN可以判断变量是否是NaN。
Infinity / -Infinity分别表示正负无穷大,正负无穷大也是number。正数除以0结果为正无穷大,负数除以0结果为负无穷大。
浮点数以64位存储,但是精度和其他语言一样是无法确定的。
类型转换
Javascript支持自动类型转换(比如整数和一个字符串用+
运算,整数会被自动转换为字符串参与拼接运算),也可以显示转换。
转换为string
数字转化为字符串:String(num),或者调用数字变量的toString()方法,比如x.toString()或者(23).toString()。
- toString(?radix):数字转换为字符串,radix表示基数(可选字段)。
- toFixed(num):数字转换为字符串,num指定小数点后保留指定的位数。
- toPrecision(num):数字转化为字符串,num指定有效数字位数。
- toExponential(?num):数字转换为指数计数法字符串,num指定
aEb
中,a的小数点后的位数。
boolean型变量转换为字符串使用String(bool)或者bool.toString()方法。
Date对象转换为字符串使用String(date)或者date.toString()方法。
Date对象方法如下:
方法 | 描述 |
---|---|
getFullYear() | 获取年 |
getMonth() | 获取月,0表示1月,1表示2月,… |
getDate() | 获取月的第几天 |
getDay() | 获取周的第几天,0表示周日,1表示周一,… |
getHours() | 获取小时 |
getMinutes() | 获取分钟 |
getSeconds() | 获取秒 |
getMilliseconds() | 获取毫秒 |
getTime() | 获取1970年1月1日至今的秒数 |
转换为number
字符串转换为数字,可以使用Number(str)方法,除非str中数字的前后包含空白字符,否则任何非法字符都会导致转换返回NaN。
- parseFloat(str)函数:将字符串str转换为浮点型number。
- parseInt(str)函数:将字符串str转换为整型number。
- +:一元运算符将字符串str转换为number,比如
+"23"
返回23。
boolean型变量转换为数字,使用Number(bool)方法,true -> 1 、false -> 0。
Date对象转换为数字,使用Number(date)方法,与date.getTime()效果一样。
关键字
abstract | else | instanceof | super | boolean | enum |
---|---|---|---|---|---|
int | switch | break | export | interface | synchronized |
byte | extends | let | this | case | false |
long | throw | catch | final | native | throws |
char | finally | new | transient | class | float |
null | true | const | for | package | try |
continue | function | private | typeof | debugger | goto |
protected | var | default | if | public | void |
delete | implements | return | volatile | do | import |
short | while | double | in | static | with |
语句
Javascript支持if语句,if…else语句,多重if..else语句,switch语句(支持default关键字,使用的是===
恒等运算符),for循环,while循环、do…while循环。
支持break语句、continue语句,其中break语句可以跳出任何代码块(冒号前面的mars相当于给大括号中的代码加了标签):
for/in循环可以遍历对象中的元素:
赋值语句返回变量的值:var a, b;console.log(a=3, b=4);
,浏览器控制台输出3 4
。
正则表达式
Javascript中,正则表达式是预定义了方法和属性的对象,其格式为:/pattern/modifiers
,其中modifiers是正则表达式修饰符,比如i
表示不区分大小写,g
表示执行全局匹配,而不是找到第一个匹配项后停止,m
执行多行匹配。
正则表达式可以用作string对象的match、search、split、replace方法的参数,正则表达式对象本身含有的方法如下:
- test()方法:检查给定的字符串中是否存在指定的模式,存在返回true,不存在返回false。
也可以从对象本身直接调用:
- exec()方法:返回匹配的字符串,如果没有匹配的部分,返回null。
代码返回:o,o
。
JSON
JSON(Javascript Object Notation)是一种轻量数据存储与交换格式,可以用在很多语言中。JSON.parse()方法可以将JSON字符串转换为JSON对象:
前后端分离的网站中,服务器后台响应给Web前端的数据格式一般是JSON。
void
void关键字表示执行某个表达式,但不返回任何结果:
输出为undefined 3 4
。
在HTML超链接中,使用<a href="javascript:void(0);">
可以实现空链接。使用< a href="#">
会导航到默认的#top
(页面顶端)。
函数
JavaScript函数采用位置参数,返回值通过return语句返回给调用者(return也可以用于跳出函数)。
在函数内部采用var声明的是局部变量,函数运行完毕删除变量;在函数外部采用var声明的变量是全局变量,关闭网页后会被删除。
如果把值赋值给未用var声明的变量,该变量自动作为全局变量,在函数外部也可以访问:
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
浏览器控制台输出3
。在HTML中,全局变量是window对象,所有数据都属于window对象,上面的变量x也可以写成window.x
。
javascript函数经常与页面事件绑定使用。
函数参数
Javascript对函数的参数不进行检查。定义函数时提供的参数叫做显式参数,调用函数时提供的参数叫做隐式参数。显式参数没有指定数据类型,隐式参数没有进行类型检测,隐式参数的个数也没有检查。如果提供的隐式参数个数不足,则显式参数的值为undefined:
浏览器控制台输出3 undefined
。一种为参数提供默认值的变通方法如下:
浏览器控制台输出3 0
。针对参数个数可变的函数,无法为每个隐式参数找到对应的参数名,可以使用函数对象的arguments属性,它是隐式参数的数组:
如果函数的隐式参数是一个对象,则是传引用,函数内对对象的修改在函数外是可见的。其他情况都是传值,函数内对值的修改,在函数外是不可见的。
匿名函数
匿名函数是没有函数名的函数,可以将其定义赋值给一个变量:
也可以定义时直接自调用:
定义函数的目的是重复利用一段代码,采用自调用的匿名函数没有这种优势。
Function对象
使用Function对象也可以定义函数:
对函数使用typeof返回function:
浏览器控制台输出:
- 1
- 2
- 1
- 2
每个函数对象都含有如下属性及方法:
- arguments:函数调用时的隐式参数组成的数组,比如通过数组的length属性获取函数调用时提供的参数个数:
- toString:以字符串形式返回函数定义。
浏览器调试窗口输出为:
函数调用
Javascript中函数有多种调用方式,不同调用方式之间,其实是this所指向的对象的区别。
- 作为全局函数调用:最基本的函数定义及调用方法,直接使用函数名调用和使用“window.函数名”的方式效果是一样的。这种情况下在函数内部访问this返回的是window对象:
浏览器控制台输出如下:
- 通过对象方法调用:将函数定义在对象的定义中,这种情况下在函数内部访问this返回的是函数所属的对象:
- 通过构造函数调用函数:
浏览器页面显示Mars Loo
,控制台输出myFunction {}
。
-
通过函数方法调用:
-
通过call()方法调用:
-
通过apply()方法调用:
-
异常处理
Javascript支持异常的抛出和捕捉,比如捕获异常(弹窗中换行使用\n
):
效果为:
使用debugger语句配合浏览器调试器可以进行单步调试:
浏览器(Firefox)中开启单步调试效果如下:
闭包
Javascript中,函数的作用域内可以访问到全局作用域的变量,但是全局作用域无法访问函数作用域内的变量。
为了在函数外能够访问到函数内的变量,可以在函数内再定义一个函数,这个内部函数能够读取外层函数的变量,并且在外层函数中返回这个内层函数:
上面的f2()函数就叫闭包,简单地讲就是能够读取其他函数内部变量的函数。其实闭包还有另外一个作用——让外层函数的变量常驻内存中:
因为f1的闭包f2被赋值给全局变量r,导致f2常驻内存,又因为f2依赖变量va,所以变量va常驻内存。函数f1内定义的add函数是全局的,可以在外部访问。
一个使用闭包封装计数器的例子:
Javascript事件
事件 | 说明 |
---|---|
onclick | 鼠标单击 |
ondblclick | 鼠标双击 |
onmousedown | 鼠标按下 |
onmouseup | 松开鼠标 |
onmouseover | 鼠标第一次移动到元素上方 |
onmouseout | 鼠标离开元素 |
onmousemove | 鼠标在元素上方移动 |
onkeydown | 键盘被按下 |
onkeypress | 键盘被按下后,字符弹出 |
onkeyup | 松开键盘 |
onaborted | 适合<img> 标签,图片加载被用户中断触发(只有IE支持) |
onload | 页面加载完成 |
onresize | 页面被调整大小时触发 |
onblur | 元素失去焦点 |
onchange | 元素失去焦点且内容发生改变 |
onfocus | 元素获得焦点 |
onsubmit | 表单提交到服务器前触发 |
函数与事件绑定举例
- 点击改变本元素文本内容:
- 本地表单验证:
将表单验证放在客户端执行,减小服务器压力(onsubmit中的代码返回false时,表单不向服务器提交):
- 弹窗:
- 改变文字颜色:
- 动态改变图片:
- 向HTML输出流中输出内容:
因为document.write()在HTML文档的头部先运行,所以输出的内容在HTML文档的body
元素的前部:
变量提升
在Javascript非严格模式下,函数的声明会被提升到脚本的开始处,变量的声明会被提升到所属代码块的最顶部,也就是变量和函数可以先使用后声明,比如:
上述代码输出:3
。变量的初始化不会被提升,比如:
上述代码输出:undefined
。
严格模式
在ES5标准中,Javascript引入了严格模式。严格模式为了和后续新标准兼容,同时也可以帮助编写更符合标准的Javascript代码。声明使用严格模式的方法是在脚本或函数的开始使用"use strict";
语句,如果该语句出现在函数定义的开头,则只在函数内部使用严格模式。
严格模式不允许使用未声明的变量,但是还是允许函数上浮:
浏览器控制台报错:
严格模式的其他要求如下:
- 不允许删除变量:
浏览器控制台报错:
- 不允许删除函数:
浏览器控制台报错:
- 不允许变量重名:
浏览器控制台报错:
- 不允许使用八进制及其转义字符:
使用八进制值时浏览器控制台报错:
使用八进制转义字符时浏览器控制台报错:
- 禁止为只读属性赋值:
浏览器控制台报错:
- 禁止为一个使用getter方法读取的属性赋值:
浏览器控制台报错:
- 禁止删除一个不允许删除的属性:
浏览器控制台报错:
- 禁止使用with语句:
浏览器控制台报错:
- 在作用域 eval() 内创建的变量在其域外不能调用:
上述代码会改变网页中id="demo"
的<p>
元素的内容,但是浏览器控制台报错:
- 禁止this指向全局window对象:
浏览器控制台输出为:
- 1
- 2
- 1
- 2
所以在严格模式下使用构造函数时,如果忘了加new,因为this不再指向全局对象:
所以浏览器会报错:
严格模式保留字
implements | interface | let |
---|---|---|
package | private | protected |
public | static | yield |
eval | arguments |
HTML DOM
HTML DOM是w3c标准,将HTML文档中所有内容都定义为节点。整个文档是document节点,每个元素是元素节点,HTML元素内的文本是文本节点(文本节点的父节点是对应的元素节点,可以通过元素节点的innerHTML属性访问文本节点的值),每个HTML属性是属性节点,注释是注释节点。
浏览器渲染HTML文档时,将整个页面解析成如下的DOM树(节点之间有父、子、同胞关系,其中root节点(<html>
元素)没有父节点。):
注:图片引自菜鸟教程。
Javascript能够通过HTML DOM改变所有的HTML元素及其属性,改变页面中所有CSS样式、对页面中所有事件做出反应。
定位元素
- 通过id获取唯一性元素:
document.getElementById("id名")
,返回找到的DOM节点,未找到返回null。 - 通过class获取不唯一元素:
document.getElementsByClassName("class名")
,返回DOM节点组成的列表,没找到返回空列表。
- 通过标签获取不唯一元素:
document.getElementsByTagsName("tag名")
添加、删除HTML DOM节点
添加或删除HTML DOM节点时,必须指定要操作节点的父节点。
添加HTML DOM节点的方法如下:
删除HTML DOM节点的方法如下:
假设s
是一个HTML DOM节点,获取其父节点的快捷方法是访问其parentNode
属性。
更新HTML DOM节点
- 改变HTML元素的内容:改变对象的innerHTML属性。
- 改变元素属性:使用“对象.属性名=属性值”的语法。使用节点的attributes属性可以获取节点的所有属性。
- 改变元素的CSS样式:使用“对象.style.样式名=样式值”的语法(
style.visibility='hidden'
或者'visible'
可以控制元素不可见、可见)。 - 响应HTML事件:
- 用户点击时,改变文本:
- 使用Javascript分配HTML DOM事件:
- 用户点击时,改变文本:
- onload事件:页面加载完成后触发,比如判断浏览器是否开启了cookie的支持:
- 各个浏览器对于onunload的支持并不好。
添加事件响应函数绑定
HTML DOM节点的addEventListener()函数可以添加事件响应监控。如果对同一个HTML DOM节点的同一个事件添加多个响应函数,这些函数不会覆盖,而是会顺序执行。
addEventListener()函数参数如下:
- event:事件,如
"click"
、"mouseup"
等。 - function:与事件绑定的响应函数。
- flag:false(默认)——按照先子元素再父元素的顺序捕获事件,true——按照先父元素再子元素的顺序捕获事件。
上面的代码的效果是点击First paragraph
文字后,先改变为日期并弹出对话框,在对话框点击确定后,文字颜色改变,因为事件监听顺序是先子元素再父元素。如果改变事件监听顺序如下:
效果变成了点击First paragraph
文字后,先改变文字颜色,再改变文字内容,最后弹出对话框。
删除事件响应函数绑定
HTML DOM对象的removeEventListener()可以删除一个事件响应函数绑定,参数如下:
- event:事件,如
"onchange"
、"onfocus"
等。 - function:事件绑定函数。
浏览器BOM
浏览器对象模型(Browser Object Model)使Javascript可以操作客户端浏览器,由于BOM并没有正式的标准,所以很多BOM的方法是不兼容的。
window
window对象表示浏览器窗口,全局变量、对象是window对象的属性,全局函数是window对象的方法。
window.open()
window.open(URL)开启一个新的浏览器窗口,该窗口将访问URL参数指定的地址。
window.close()
window.close()方法关闭一个浏览器窗口。
window.location
window.location对象用于获取当前页面的URL,其含有如下属性:
- href属性可以获取当前页面的URL。
- protocal属性获取使用的协议。
- hostname属性获取web主机的域名。
- port属性获取web主机的端口。
- pathname属性获取页面的路径。
- assign()方法加载新的文档。
- 1
- 2
- 3
- 1
- 2
- 3
window.history
window.history对象访问浏览器历史,其back()方法返回上一页,forward()方法返回前一页。
确认框
除了window.alert()以外,confirm(msg)方法可以弹出确认框,msg是确认框中的提示信息,比如:
- 1
- 2
- 1
- 2
效果为:
其返回值为true/false,分别对应点选“确定”/”取消”。
提示框
window.prompt(msg, default)可以弹出提示框,其中msg参数是提示框中的提示信息,default参数提供提示框的默认值,方法返回用户在提示框中填写的值,比如:
- 1
- 2
- 1
- 2
效果如下:
计时事件
setInterval()/clearInterval()
setInterval(function_name, interval)方法将function_name对应的函数间隔interval时间(以ms为单位)执行,返回一个计时器对象用于作为clearInterval()的参数以清除这个计时器对象,比如:
function_name也可以是定义函数的字符串,比如:
setTimeout()/clearTimeout()
setTimeout()方法的参数和setInterval()方法的参数相同,不同之处在于setTimeout()指定在一段时间间隔之后执行一次函数,clearTimeout()方法用来在超时之前删除计时事件绑定。比如:
cookie
document.cookie对象代表浏览器端的cookie,直接将如下格式的字符串赋值给这个对象即可:"key=value;expires=Thu, 18 Dec 2013 12:00:00 GMT;path=/;domain=localhost"
。
添加cookie
浏览器控制台可以看到设置了name=mars
,过期时间3天以后,访问路径为/
,访问域为localhost
的cookie:
添加新的cookie可以再次直接赋值给document.cookie对象:
浏览器中可以看到增加了一项cookie:
修改cookie
修改cookie可以直接在key=value;
中替换新的value
,然后将新的字符串赋值给document.cookie即可:
浏览器中可以看到,username这项cookie值已经被改变:
获取cookie
读取cookie可以采用正则表达式,比如:
如果cookie不止一条,则多个cookie之间可能存在分号及空格:
浏览器控制台输出如下:
username=marsloo; name=susonloo
删除cookie
删除cookie,将其有效期设置为当前时间之前即可:
浏览器控制台可以看到username=marsloo
的cookie已经被删除: