前身:liveScript
起源:诞生于1995年,主要的作用是处理网页中的前端验证。
最初用来做前端验证(而并不是后端服务器验证):检查用户输入的内容是否符合一定的规则(用户名的长度,邮箱的格式)
不同的浏览器对JavaScript实现的引擎是不同的。
JavaScript一般包含以下三个部分:ECMAScript/DOM/BOM
JS的特点:
JS代码需要编写到script标签中,这个标签有一个type属性,默认为“text/javascript”
1 | alert("Hello World!"); //发出提醒 |
1 | <!--可以将js代码编写到onclick属性中--> |
优点:降低了程序的耦合度,写到外部的文件可以在不同的页面中同时引用,也可以利用浏览器的缓存机制
注意:script 标签一旦用来引入外部文件,就不能再编写代码了,即使编写了,浏览器也会忽略,只能再写一个script标签来编写内部的代码。
1 |
|
注释:
代码规则:
变量/标识符
使用var声明一个变量,可以同时赋值
js底层保存的标识符是采用Unicode,所以,理论上u8中所有的字符都能作为变量名
1 | <script> |
在js中一共有6中数据类型
其中12345是基本数据类型,6是引用数据类型
String:
Number
使用方式:
1 | /* |
类型转换主要指:将其他类型转换为 String Number Boolean转换为 String 类型:
1 | // 法1 |
使用Number()函数
1.如果是纯数字的字符串,则直接将其转换为数字
2.如果字符串中有非数字的内容,则转换为NaN
3.如果字符串是空串、全是空格的字符串、false、null,则转换为0
4.undefined 为 NaN
parseInt()函数和 parseFloat()函数 专门用来对付字符串
调用Boolean()函数来将a转换为布尔值
在js中,如果需要表示16进制的数字,则需要以0x开头如果需要表示8进制的数字,则需要以0开头如果要要表示2进制的数字,则需要以0b开头但是不是所有的浏览器都支持,像”070”这种字符串,有些浏览器会当成8进制解析,有些会当成10进制解析
如果对非String使用parseInt()或parseFloat()它会先将其转换为String然后再操作
1 | var a = "123.456px" |
基本和java一样
任何值和字符串相加都会转换为字符串,并做拼串操作。我们可以利用这一特点,来将一个任意的数据类型转换为String我们只需要为任意的数据类型 + 一个 “” 即可将其转换为String这是一种隐式的类型转换,由浏览器自动完成,实际上它也是调用String()函数
任何值做- * /运算时都会自动转换为Number我们可以利用这一特点做隐式的类型转换可以通过为一个值 -0 *1 /1 来将其转换为Number原理和Number()函数一样,使用起来更加简单(但是不是我们的最终方式,我们还有其他的方式)。
以下运算符和java一样:
= = = 全等:在比较的时候不会进行自动类型转换,如果类型不同会直接返回false
! = = 不全等 同理
比较两个字符串型的数字的时候一定一定要转型
也有与或非运算符,而且我们可以对一个值取两次反(两次‘!’)来将其转换为布尔值
在JS中可以使用 {} 将语句括起来进行分组,(只有分组的作用,没有其他用途,代码块中的内容在外部是完全可见的)
prompt函数接受一个参数作为输出,弹出一个对话框,接受用户输入,作为返回值。
1 | var score = prompt("请输入小明的期末成绩(0-100):"); |
JS中的顺序、分支和循环语句和Java中一模一样
Js中的数据类型:String, Number, Boolean, Null, Undefined
只要不属于这五种数据类型,都是对象 Object
对象分为内建对象(ES标准中定义的对象 Math\String\Number\Function)、宿主对象(BOM\DOM)、自定义对象(我们自己创建的对象)
使用 new 关键字调用的函数时构造函数(专门用来创建对象的函数)
每个对象中都有一个constructor属性,它引用了当前对象的构造函数。
对对象的基本操作
对象中的保存的值称为属性,属性可以是任意类型,包括对象,也可以是个函数
向对象中添加属性,语法:对象.属性名 = 属性值;
读取对象中的属性,语法:``对象.属性名;(如果对象中没有这个属性,不会报错,而是返回 undefined)或者 对象[属性名] = 属性值`
修改对象的属性,语法:对象.属性名 = 新值;
删除对象的属性,语法:delete 对象.属性名
1 | var obj = new Object(); |
in 运算符:检查一个对象中是否含有指定的属性,有就返回true,否则返回false;语法:"属性名" in 对象
1 | console.log("name" in obj); |
js中的变量都是保存在栈中的,但是对象是保存在堆中的,保存的都是引用
当比较两个基本数据类型的时候是比较值,但是在比较两个引用数据类型的时候,比较的是对象的内存地址,即使两个对象的内容都一样,只要地址不一样,还是会返回false
使用对象字面量创建对象:
使用对象字面量,在创建对象的时候,直接指定对象中的属性,语法:{属性名:属性值,属性名:属性值,...}对象字面量的属性名可以加上引号,也能不加,建议不加,如果要使用一些特殊的名字,就必须加上引号
属性名和属性值是一组一组的名值对结构,每一组之间用,隔开,名值之间用:链接
1 | var obj2 = { |
函数也是对象,而且 typeof 函数 = function
1 | // 将代码以字符串的形式传递给对象(函数表达式) |
含参数的函数的声明:
1 | function sum(a, b){ |
调用函数时解析器不会检查实参的类型,所以要注意,是否有可能会接收到非法的参数,如果有可能则需要对参数进行类型的检查函数的实参可以是任意的数据类型
调用函数时,解析器也不会检查实参的数量, 多余实参不会被赋值如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined
函数中不写return,会返回undefined
声明完毕立即执行的函数:
1 | (function(a, b){ |
枚举对象中的属性
1 | var student = { |
作用域指一个变量的作用的范围
在JS中一共有两种作用域:
全局作用域 和 函数作用域
全局作用域:
函数作用域:
变量声明提前:
变量的声明提前: 使用var关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值,如果这时候输出,会显示undefined),但是如果声明变量时不适用var关键字,则变量不会被声明提前
函数的声明提前: 使用函数声明形式创建的函数 function 函数(){}它会在所有的代码执行之前就被创建,所以我们可以在函数声明前来调用函数, 使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用
1 | //函数声明,会被提前创建 |
解析器在调用函数每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就是this,this指向的是一个对象, 这个对象我们称为函数执行的 上下文对象,根据函数的调用方式的不同,this会指向不同的对象
1.以函数的形式调用时,this永远都是window
2.以方法的形式调用时,this就是调用方法的那个对象
1 | this.name = 'windows!!' |
函数中还有一个对象arguments,这个对象是一个数组,用来保存函数的参数,并且这个对象还有一个属性callee来表示当前的函数
使用工厂方法创造对象:
1 | function createPerson(name , age ,gender){ |
缺点:创建的对象都是Object这个类型,就导致我们无法区分出多种不同类型的对象
构造函数:
构造函数和普通函数的区别就是调用方式的不同,普通函数是直接调用,而构造函数需要使用new关键字来调用
构造函数的执行流程:
this的情况:
1 | function Person(name , age , gender){ |
使用instanceof可以检查一个对象是否是一个类的实例
语法:对象 instanceof 构造函数. 如果是,则返回true,否则返回false
所有的对象都是Object的后代,所以任何对象和Object左instanceof检查时都会返回true
创建一个函数以后,解析器都会默认在函数中添加一个属性prototype,prototype属性指向的是一个对象,这个对象我们称为原型对象。如果函数作为普通函数调用prototype没有任何作用
当函数作为构造函数使用,它所创建的对象中都会有一个隐含的属性执行该原型对象。这个隐含的属性可以通过 对象. __proto__来访问。
原型对象就相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象。我们可以将对象中共有的属性和方法统一添加到原型对象中,这样我们只需要添加一次,就可以使所有的对象都可以使用。
当我们去访问对象的一个属性或调用对象的一个方法时,它会先自身中寻找,如果在自身中找到了,则直接使用。如果没有找到,则去原型对象中寻找,如果找到了则使用,如果没有找到,则去原型的原型中寻找,依此类推。直到找到Object的原型为止,Object的原型的原型为null,如果依然没有找到则返回undefined
hasOwnProperty()
这个方法可以用来检查对象自身中是否含有某个属性
语法:对象.hasOwnProperty(“属性名”)
toString 方法:
1 | function Person(name , age , gender){ |
成员变量
创建数组:var arr = new Array(); 或者 var arr = [1,2,3,4,5]; 第一种方法如果是一个参数,就代表元素的个数,如果是多个,就代表每个元素的值
获取数组的长度数组名称.length
修改length的时候,如果修改的length大于原长度,则多出部分会空出来,如果修改的length小于原长度,则多出的元素会被删除
向数组的最后一个位置添加元素,语法:数组[数组.length] = 值;
如果读取不存在的索引,他不会报错而是返回undefined
方法
push()
pop()
unshift()
shift()
slice()
splice()
reverse()
concat()
join()
sort()
1 | function(a,b){ |
数组的遍历:
forEach()方法需要一个函数作为参数
这个方法只能遍历数组,不能遍历伪数组
像这种函数,由我们创建但是不由我们调用的,我们称为回调函数
数组中有几个元素函数就会执行几次,每次执行时,浏览器会将遍历到的元素以实参的形式传递进来,我们可以来定义形参,来读取这些内容
浏览器会在回调函数中传递三个参数:
1 | arr.forEach(function(value , index , obj){ |
String() Boolean() Number()
当我们去操作一个基本数据类型的属性和方法时,解析器会临时将其转换为对应的包装类,然后再去操作属性和方法,操作完成以后再将这个临时对象进行销毁。
构造函数:var d = new Date(); 默认是当前代码的执行时间。
带参构造:var d2 = new Date("2/18/2011 11:10:30");日期的格式 月份/日/年 时:分:秒
get相关的函数
1 | //getDate() 获取当前日期对象是几日 |
1 | Math.PI //表示的圆周率 |
创建正则表达式对象:var 变量 = new RegExp("表达式", "匹配模式");
typeof 正则表达式 = object
在构造函数中可以传递一个匹配模式作为第二个参数,可以是i 忽略大小写 ,g 全局匹配模式
test() 使用这个方法可以用来检查一个字符串是否符合正则表达式的规则,如果符合则返回true,否则返回false
使用字面量来创建正则表达式语法:var 变量 = /正则表达式/匹配模式
使用字面量的方式创建更加简单,使用构造函数创建更加灵活
var reg = /a/i;
正则表达式的相关内容查看 正则表达式.pdf
DOM,全称Document Object Model文档对象模型。以面向对象的方式操作网页。
文档 – 文档表示的就是整个的HTML网页文档
对象 – 对象表示将网页中的每一个部分都转换为了一个对象。
模型 – 使用模型来表示对象之间的关系,这样方便我们获取对象。
节点:Node——构成HTML文档最基本的单元
常见节点:
文档节点:整个HTML文档
元素节点:HTML文档中的HTML标签
属性节点:元素的属性
文本节点:HTML标签中的文本内容
节点的属性:
| nodeName | nodeType | nodeValue | |
|---|---|---|---|
| 文档节点 | #document |
9 | null |
| 元素节点 | 标签名 | 1 | null |
| 属性节点 | 属性名 | 2 | 属性值 |
| 文本节点 | #text |
3 | 文本内容 |
document对象作为window对象的属性存在的,我们不用获取可以直接使用。通过该对象我们可以在整个文档访问内查找节 点对象,并可以通过该对象创建各种节点对象。
举例:通过id获取一个元素节点的对象:– document.getElementById()
事件处理有两种方法
<button id="btn" onclick="alert('点我干嘛?');">我是一个按钮</button>这样当事件被触发时,这些代码将会执行这种写法我们称为结构和行为耦合,不方便维护,不推荐使用。1 | <button id="btn">我是一个按钮</button> |
注意:
浏览器在加载一个页面时,是按照自上向下的顺序加载的,读取到一行就运行一行,如果将script标签写到页面的上边,在代码执行时,页面还没有加载,页面没有加载DOM对象也没有加载会导致无法获取到DOM对象
如何在写到上面的同时使其在页面加载完之后执行?
onload事件会在整个页面加载完成之后才触发, 为window绑定一个onload事件该事件对应的响应函数将会在页面加载完成之后执行,这样可以确保我们的代码执行时所有的DOM对象已经加载完毕了。
1 | window.onload = function(){ |
获取元素节点:
通过document对象调用
1 | // 通过id属性获取一个元素节点对象 |
获取元素节点的子节点:
通过具体的元素节点调用。
1 | //方法,返回当前节点的指定标签名后代节点 |
注意:
childNodes属性会获取包括文本节点在内的所有节点,根据DOM标签标签间空白也会当成文本节点。注意:在IE8及以下的浏览器中,不会将空白文本当成子节点,所以该属性在IE8中会返回4个子元素而其他浏览器是9个
firstElementChild不支持IE8及以下的浏览器,如果需要兼容他们尽量不要使用
获取父节点和兄弟节点:
通过具体节点调用
1 | //属性,表示当前节点的父节点 |
元素节点的属性
1 | //--------------获取----------- |
文本框的value属性值,就是文本框中填写的内容
文本节点可以通过nodeValue属性获取和设置文本节点的内容
元素节点通过innerHTML属性获取和设置标签内部的 html代码
innerText属性可以获取到元素内部的文本内容,它和innerHTML类似,不同的是它会自动将html去除
为指定元素绑定单击响应函数的快捷方法:函数
1 | /* |
多选框的选中状态是元素的属性,值为布尔类型,通过设置checked属性可以设置选中和未选中。在事件的响应函数中,响应函数是给谁绑定的this就是谁。
1 | //在document中有一个属性body,它保存的是body的引用 |
class的选择
根据元素的class属性值查询一组元素节点对象: getElementsByClassName()可以根据class属性值获取一组元素节点对象,但是该方法不支持IE8及以下的浏览器
document.querySelector()
var div = document.querySelector(".box1 div");document.querySelectorAll()
box1 = document.querySelectorAll("#box2");document.createElement()可以用于创建一个元素节点对象,它需要一个标签名作为参数,将会根据该标签名创建元素节点对象,并将创建好的对象作为返回值返回
document.createTextNode()可以用来创建一个文本节点对象,需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新的节点返回
appendChild()用于向一个父节点中添加一个新的子节点,用法:父节点.appendChild(子节点);
insertBefore()可以在指定的子节点前插入新的子节点.语法,父节点.insertBefore(新节点对象, 子节点对象);
replaceChild()可以使用指定的子节点替换已有的子节点,语法:父节点.replaceChild(新节点,旧节点);
removeChild()删除一个子节点,语法:父节点.removeChild(子节点);子节点.parentNode.removeChild(子节点);
注意:使用innerHTML也可以完成DOM的增删改的相关操作,一般我们会两种方式结合使用
1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> |
元素.style.样式名 = 样式值, 通过JS修改元素的样式:注意:如果CSS的样式名中含有-,这种名称在JS中是不合法的比如background-color需要将这种样式名修改为驼峰命名法,也就是去掉-,然后将-后的字母大写. 我们通过style属性设置的样式都是内联样式,而内联样式有较高的优先级,所以通过JS修改的样式往往会立即显示, 但是如果在样式中写了!important,则此时样式会有最高的优先级,即使通过JS也不能覆盖该样式,此时将会导致JS修改样式失效, 所以尽量不要为样式添加!important, 通过style属性设置和读取的都是内联样式,无法读取样式表中的样式
元素.currentStyle.样式名, 获取元素的当前显示的样式。currentStyle只有IE浏览器支持,其他的浏览器都不支持。它可以用来读取当前元素正在显示的样式, 如果当前元素没有设置该样式,则获取它的默认值
window.getComputedStyle(box1,null).backgroundColor, 在其他浏览器中可以使用,getComputedStyle()这个方法来获取元素当前的样式;需要两个参数: 第一个:要获取样式的元素; 第二个:可以传递一个伪元素,一般都传null。 该方法会返回一个对象,对象中封装了当前元素对应的样式,可以通过对象.样式名来读取样式,如果获取的样式没有设置,则会获取到真实的值,而不是默认值比如:没有设置width,它不会获取到auto,而是一个长度; 但是该方法不支持IE8及以下的浏览器, 通过currentStyle和getComputedStyle()读取到的样式都是只读的,不能修改,如果要修改必须通过style属性
定义一个函数,用来获取指定元素的当前的样式
1 | //obj 要获取样式的元素 |
clientWidth/clientHeight
offsetWidth/offsetHeight
offsetParent
offsetLeft
scrollWidth/scrollHeight
scrollLeft
判断滚动条是否滚动到底
事件对象:在DOM对象上的某个事件被触发时,会产生一个事件对象Event,这个对象中包含着所有事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。
例如,鼠标操作导致的事件对象中,会包含鼠标位置的信息,而键盘操作导致的事件对象中,会包含与按下的键有关的信息。所有浏览器都支持 event对象,但支持方式不同。
DOM标准的浏览器会将一个event对象传入到事件的处理程序当中。无论事件处理程序是什么都会传入一个event对象。Event对象包含与创建它的特定事件有关的属性和方法。触发的事件类型不一样,可用的属性和方法也不一样。
事件的发生主要是由用户操作引起的。,比如mousemove这个事件就是由于用户移动鼠标引起的,在鼠标指针移动的过程中该事件会持续发生。当指定事件被触发时,浏览器就会调用对应的函数去响应事件,一般情况下事件没触发一次,函数就会执行一次。因此设置鼠标移动的事件可能会影响到鼠标的移动速度。所以设置该类事件时一定要谨慎。
获取方式:
1 | // 向其中传入一个event参数 |
当鼠标在areaDiv中移动时,在showMsg中来显示鼠标的坐标
1 | /* |
事件的冒泡(Bubble)
event.cancelBubble = true;可以将事件对象的cancelBubble设置为true,即可取消冒泡
我们希望,只绑定一次事件,即可应用到多个的元素上,即使元素是后添加的, 因此我们可以尝试将其绑定给元素的共同的祖先元素
事件的委派, 指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素, 从而通过祖先元素的响应函数来处理事件。事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
使用 对象.事件 = 函数 的形式绑定响应函数,它只能同时为一个元素的一个事件绑定一个响应函数,不能绑定多个,如果绑定了多个,则后边会覆盖掉前边的。
addEventListener() 通过这个方法也可以为元素绑定响应函数
参数:
事件的字符串,不要on
回调函数,当事件触发时该函数会被调用
是否在捕获阶段触发事件,需要一个布尔值,一般都传false
使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,这样当事件被触发时,响应函数将会按照函数的绑定顺序执行,这个方法不支持IE8及以下的浏览器
attachEvent()在IE8中可以使用attachEvent()来绑定事件
参数:
这个方法也可以同时为一个事件绑定多个处理函数,不同的是它是后绑定先执行,执行顺序和addEventListener()相反
定义一个函数用来为指定元素绑定响应函数
1 | /* |
关于事件的传播网景公司和微软公司有不同的理解: 微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行;网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件, 然后在向内传播给后代元素
W3C综合了两个公司的方案,将事件传播分成了三个阶段
如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true, 一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
IE8及以下的浏览器中没有捕获阶段
事件的传播流程
捕获阶段 – 这一阶段会从window对象开始向下一直遍历到目标对象,如果发现有对 象绑定了响应事件则做相应的处理。
目标阶段 – 这一阶段已经遍历结束,则会执行目标对象上绑定的响应函数。
事件冒泡阶段 – 这一阶段,事件的传播方式和捕获阶段正好相反,会从事件目标一直向遍历,直至window对象结束,这时对象上绑定的响应函数也会执行
我们可以使用event对象的两个方法完成: – stopPropagation() – stopImmediatePropagation()
取消默认行为: – preventDefault()
拖拽事件, 滚轮事件, 键盘事件等略, 都是调用api, 在使用的时候查阅即可
BOM将浏览器中的各个部分转换成了一个一个的对象,我们通过修改这些对象的属性,调用他们的方法,从而控制浏览器的各种行为。
window对象是BOM的核心,它表示一个浏览器的实例。在浏览器中我们可以通过window对象来访问操作浏览器,同时window也是作为全局对象存在的。全局作用域: window对象是浏览器中的全局对象,因此所有在全局作用域中声明的变量、对象、函数都会变成window对象的属性和方法。
窗口大小
浏览器中提供了四个属性用来确定窗口的大小:
– 网页窗口的大小 innerWidth / innerHeight
– 浏览器本身的尺寸 outerWidth / outerHeight
打开窗口
使用 window.open() 方法既可以导航到一个特定的 URL,也可以打开一个新的浏览器窗口。 这个方法需要四个参数:
需要加载的url地址
窗口的目标
一个特性的字符串
是否创建新的历史记录
超时调用
setTimeout() 超过一定时间以后执行指定函数 – 需要两个参数: 要执行的内容/超过的时间
延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次
延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次
延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择
取消超时调用 – clearTimeout() 超时调用都是在全局作用域中执行的。
间歇调用
setInterval() 每隔一段时间执行指定代码 , 需要两个参数: 要执行的代码(回调函数) ; 间隔的时间,单位是毫秒; 返回一个Number类型的数据,这个数据用来作为定时器的唯一标识
取消间隔调用: – clearInterval()
1 | var timer = setInterval(function(){ |
系统对话框
浏览器通过 alert() 、 confirm() 和 prompt() 方法可以调用系统对话框向用户显示消息。它们的外观由操作系统及(或)浏览器设置决定,而不是由 CSS 决定。显示系统对话框时会导致程序终止,当关闭对话框程序会恢复执行。
location代表当前浏览器的地址栏信息,还提供了一些导航功能,通过Location可以获取地址栏信息,或者操作浏览器跳转页面。
如果直接将location属性修改为一个完整的路径,或相对路径,则我们页面会自动跳转到该路径,并且会生成相应的历史记录
href属性:
assign() 方法
replace()方法
reload() 方法
代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器, 由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了, 一般我们只会使用userAgent来判断浏览器的信息,userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,不同的浏览器会有不同的userAgent
navigator 对象包含了浏览器的版本、浏览器所支持的插件、浏览器所使用的语言等各种与浏览器相关的信息。
我们有时会使用navigator的userAgent属性来检查用户浏览器的版本。
history 对象保存着用户上网的历史记录,从窗口被打开的那一刻算起。由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页而且该操作只在当次访问时有效
go()
back()
forward()
JSON
JSON中允许的值:
1.字符串
2.数值
3.布尔值
4.null
5.对象
6.数组
json –> js对象
JSON.parse()
JS对象 —> JSON
JSON.stringify()
eval()