一、变量的类型
1.原始类型
JavaScript共有5种原始类型,如下
boolean 布尔,值为true或false
number 数字,值为任何整型或浮点数值
string 字符串,值为单引号或双引号括出的单个字符
null 空类型,该原始类型仅有一个值:null
undefined 未定义,该原始类型仅有一个值:undefined(undefined会被赋值给一个还没有初始化的变量)
前3种类型(boolean,number和string)表现的行为类似,而后两种(null和undefined)则有一点区别
一般用typeof操作符判断变量类型
注意:typeof判断引用类型的数据,除了Function返回function其他都返回object
var num = 10;
var str = "hello world";
var b = true; /* boolean true false */
/* typeof 操作符去判断 */
console.log(typeof num)
console.log(typeof str)
console.log(typeof b)
/* typeof 操作符可能的返回值
undefined------如果这个值未定义
boolean ------如果这个值是布尔值
string ------如果这个值是字符串
number ------如果这个值是数值
object ------如果这个值是对象或null
function ------如果这个值是函数
*/
2.引用类型
JavaScript中引用类型有Array、Date、Function、Object、Error、RegExp
引用类型的值是保存在内存中的对象中,与其他语言不同,JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对线的内存空间,在操作对象时,实际上是在操作对象的引用而不是实际的对象。
数组
/* 1.声明一个数组 */
var arr = ["html","css","js"];
/* 2.Array.isArray() 判断一个对象是不是一个数组 */
console.log(Array.isArray(arr))
console.log(arr instanceof Array);
/* 3.读取数组的值 */
console.log(arr[0])
console.log(arr[2])
/* 4. length属性可以获取数组的长度 */
console.log(arr.length)
/* 5.获取数组的最后一位的值 */
console.log(arr[arr.length-1])
数组的添加和删除
//1.push():栈方法,在数组最后面插入项,返回数组的长度
数组改后的长度 = 数组.push(元素);
//2.pop():取出数组中最后一个元素,返回被删除的元素
被删除的元素 = 数组.pop(); //注意括号里不含参数
//3.unshift():队列方法,在数组最前面插入项,返回数组长度
//4.shift():取出数组中的第一个元素,返回被删除的元素
函数
函数是封装一个特定功能的代码块,函数不调用不会执行
var go = function(x){
console.log(x)
}
go(20);
对象
/* json对象 key,value的形式出现的 */
var cheng = {
"name":"chengchao",
age:20,
sex:"男"
}
/* 2.读取对象属性的值 */
console.log(cheng.name)
/* Tip:如果属性名是变量的情况下,使用中括号去读取 */
console.log(cheng["name"])
/* 3.给对象新添加一个属性 */
cheng.love= "看电影"
console.log(cheng)
/* 4.读取对象所有的属性 Object.keys(obj)*/
console.log(Object.keys(cheng))
/* 5.读取对象所有的value值 Object.values(obj) */
console.log(Object.values(cheng))
/* 6.for in遍历对象 */
for(var k in cheng){
console.log(k); //这里打印的是key
console.log(cheng[k]); //这里打印的是value(用到了2中的tip)
}
3.全局变量和局部变量
全局变量:可以在脚本中的任何位置被引用。一旦你在某个脚本里声明了一个全局变量,就可以从这个脚本中的任何位置(包括函数内部)引用它。全局变量的作用域使整个脚本。
局部变量:只存在于声明它的那个函数的内部,在那个函数的外部是无法引用它的。局部变量的作用域仅限于某个特定的函数。
函数中引用了全局变量
var a=10;
function go(){
a=20; //这里直接写a=20是引用了全局变量a
return a;
}
b = go();
console.log("a="+a);
console.log("b="+b);
输出结果
把这个函数写成这样才正确
var a=10;
function go(){
var a=20; //加上var之后,函数里的a就是局部变量,和外面的a没关系
return a;
}
b = go();
console.log("a="+a);
console.log("b="+b);
二、JS基本语法
1.声明提前
es6语法以前JavaScript在执行代码的时候会将所有使用var声明的变量,放在作用域的顶部集中创建,赋值留在原地
console.log("a="+a);
var a = 20;
//输出结果为a=undefined
2.数据类型转换
字符串和布尔转成数字
Number()强制转换
var a="12.132";
var bool = true;
var num1 = Number(a); //num1为12.132
var num2 = Number(bool); //num2为1
缺点:Number()只能识别纯数字的字符串,遇到字符串中含由非数字的会返回NaN
parseInt和parseFloat
var str = "12.323px";
console.log(Number(str)); //输出为NaN
console.log(parseInt(str)); //输出为12
console.log(parseFloat(str)); //输出为12.323
开头的字符必须以数字开头,遇到非数字的字符就停止解析
另外,parseInt还可以将其他进制的数转化为十进制
/* JavaScript里面:
八进制的数都是以0开头,类似:0750,060
十六进制的数都是0x开头,类似:0xAF,0x5631
在ECMA3中,“070”会被当成八进制字面量,会被转化为十进制的56
“0xAF”会被当成十六进制字面量,会被转换为175*/
var a = 012;
var b = 0xAF
console.log(a);//输出会是10
console.log(b);//输出会是175
/*parseInt()函数提供了第二个参数:转换时使用的基数(即多少进制)*/
var num1 = parseInt("012",8); //10
/*注意这里的012一定要用引号包住,否则会先被转换为10,然后成了parseInt(10,8)*/
var num2 = parseInt("0xAF",16); //175
数字转成字符串和布尔
转字符串用String()或者toString(),注意toString是用num.toString()调用的
转布尔用Boolean()方法
注意只有5种情况才会返回false:1.”” 2.NaN 3.undefined 4.null 5.0
自动转换
算数计算中,先将两边的变量转换为Number再计算Number()
特殊情况:加运算中,碰到字符串,+会起到拼接符的作用
加法运算
var a = 1;
var b = true;
var d = "2"
var c = "hello world";
var str = a+b;
var sum = a+c;
console.log(str);
console.log(sum)
console.log(a+d);
减法运算
var a = true;
var b = "3";
var c = 4;
console.log(a-b);
/* Number(a)-Number(b) */
console.log(c-b);
console.log(c-a);
3.运算符和表达式
比较运算符
>,<,>=,<=,==,!=
遇到比较运算符的时候会将对两边变量用number()方法,转换成Number类型再比较
/*
>,<,>=,<= 比较运算返回的结果是boolean
先将两边的值转换为Number再比较
*/
var a = 10;
var b = "20"
var c = "true"
console.log(a>b); //false
// Number(a)>Number(b)
console.log(a>c);
// Number(a)>Number(c) 10>NaN NaN是不能参与计算的,它和任何值做计算,结果都是NaN
在转换的过程中会有特殊情况,例如字符串转数字会出现NaN
特殊情况NaN:NaN不等于,不大于,不小于任何值(包括自己)。 用isNaN(n):用来判断n是否为NaN
三目运算符
表达式?值1:值2
如果表达式为真 返回值1
如果表达式为假 返回值2
注意:值1和值2类型要一致
var a = 30;
var b = 20;
var c = (a>b)?"a大于b":"a小于b";
console.log(c)
相等和全等
一、相等(==)和不相等(!=)
相等和不相等这两个操作符都会先转换操作数(通常称为强制转型),然后再比较它们的相等性
在转换不同的数据类型时,相等和不相等遵循下列基本规则:
1.如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前会先将字符串转换为数值
var s = "123";
var num = 123;
console.log(s==num); //true
2.如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较;
var num1 = new Number(13); //num1为对象类型
var num2 = 13; //num2为number基本类型
console.log(num1==num2); //先去num1.valueOf()得到number类型的13,然后再比较
3.null和undefined是相等的,并且在比较相等性之前,不能将null和undefined转换成其他数据类型
undefined == 0; //false
null == 0; //false
undefined == false; //false
null == false; //false
4.如果有一个操作数是NaN,则相等操作符返回false
注意:NaN不等于任何数,包括他自己
5.如果两个操作数都是对象
如果两个都是对象(object)类型,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则是相等操作符返回true,否则返回false。
var num1 = new Number(1);
var num2 = new Number(1);
console.log(num1==num2); //false
//尽管这两个对象的valueOf()相等,但是不同的两个对象,并不是指向同一个对象
二、全等和不全等
除了在比较之前不转换操作数之外,全等和不全等与相等和不相等操作符没有什么区别。全等操作符只在两个操作数未经转换就相等的情况下返回true。
var num1 = new Number(1); //类型为对象
var num2 = 1; //类型为数字
var result1 = (num1==num2); //true,因为转换后相等
var result2 = (num1===num2); //false,因为不同的数据类型不相等
三、DOM
1.什么是DOM
DOM:文档对象模型。DOM 为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。目的其实就是为了能让js操作html元素而制定的一个规范。
整个DOM体系可以用一棵DOM树来表示。
DOM树是由一个个节点组成
上图可知,在HTML中,一切都是节点;
- 元素节点:Html标签(nodeType==1)
- 属性节点:标签的属性(nodeType==2)
- 文本节点:标签中的文字(nodeType==3)
2.DOM节点和访问关系的获取
dom节点的获取
<p name="test" class="one" id="only-id">hello world</p>
<script>
var onlyid = document.getElementById("only-id");//通过id获取单个标签
//以下四种方式获取到的都是集合
var one = document.getElementsByClassName("one");
var p = document.getElementsByTagName('p');
var test = document.getElementsByName("test");
//querySelectorAll方法就就和选择器一样,是class就用.xxx,是id就用#xxx
var query = document.querySelectorAll("#only-id")
<script>
dom访问关系的获取
dom的节点并不是孤立的,因此可以通过dom节点之间的相对关系对它们进行访问。js中的父子访问关系如下:
1.获取父节点
调用者就是一个子节点,一个节点只有一个父节点,调用方式为
var parent = 节点.parentNode;
2.获取兄弟节点
var sibling1 = 节点.nextSibling;//获取下一个节点(包括标签,空文档,文本节点)
var sibling2 = 节点.nextElementSibling;//获取下一个元素节点
//next表示后面的,前面的用previous,用法同理
3.获取单个子节点
var firstchild1 = 父节点.firstChild;//获取下一个节点
var firstchild2 = 父节点.firstElementChild;//获取下一个元素节点
//first表示第一个,最后一个用last,用法同理
4.获取所有的子节点
var 子节点数组1 = 父节点.childNodes;//获取所有子节点,用的少
var 子节点数组2 = 父节点.children;//用的最多,得到了几乎所有游览器的支持
3.DOM节点的操作
创建节点
格式:var 要创建节点名 = document.createElement(“标签名”);
//例如我们想要创建li标签
<script type="text/javascript">
var a1 = document.createElement("li"); //创建一个li标签
var a2 = document.createElement("adbc"); //创建一个不存在的标签
console.log(a1);
console.log(a2);
console.log(typeof a1);
console.log(typeof a2);
</script>
控制台输出结果:
插入节点
插入节点有两种方式,它们的含义是不同的
方式1:
父节点.appendChild(新的子节点); //父节点的最后插入一个新的子节点
方式2:
父节点.insertBefore(新的子节点,作为参考的子节点);
//在参考节点前插入一个新的节点。如果参考节点为null,那么他将在父节点最后插入一个子节点
修改节点
父节点.repalceChild(新的子节点,老的被替换的节点)
删除节点
格式如下:
父节点.removeChild(子节点);
解释:用父节点删除子节点。必须要指定是删除哪个子节点。
如果想要自己删除自己,可以这么做:
node1.parentNode.removeChild(node1);
复制节点
格式如下:
要复制的节点.cloneNode(); //括号里不带参数和带参数false,效果是一样的。
要复制的节点.cloneNode(true);
括号里带不带参数,效果是不同的。解释如下:
- 不带参数/带参数false:只复制节点本身,不复制子节点。
- 带参数true:既复制节点本身,也复制其所有的子节点。
设置节点属性
1.获取节点的属性值
元素节点.getAttribute("属性名称");
举例:
<img src="images/1.jpg" class="image-box" title="美女图片" alt="地铁一瞥" id="a1">
<script>
console.log(myNode.getAttribute("src"));
console.log(myNode.getAttribute("class")); //注意是class,不是className
console.log(myNode.getAttribute("title"));
</script>
2.设置节点的属性值
元素节点.setAttribute(属性名,属性值);
//举例(设置节点的属性值)
myNode.setAttribute("src","images/3.jpg");
myNode.setAttribute("class","image3-box");
myNode.setAttribute("id","你好");
//注意,两个值都需要用引号包着
3.删除节点的属性
元素节点.removeAttribute(属性名);
4.DOM事件(event)
JavaScript与HTML之间的交互通过事件实现的
onclick
onfocus
onblur
onmouseover //鼠标移到某元素之上
onmouseout //鼠标从某元素移开
onload页面加载时触发
onchange域的内容改变时发生
onsubmit//表单中的确认按钮被点击时发生
//有事件一定有对应一个处理结果,用函数表示
onresize//浏览器的尺寸发生改变
onscroll //窗口滚动
onchange事件支持的标签input,select,textarea
键盘事件与keycode属性
onkeydown:用户按下一个键盘按键时发生
onkeypress:在键盘按键按下并释放一个键时发生
onkeyup:在键盘按键松开时发生
keyCode:返回onkeypress,onkeydown或onkeyup事件触发的键的值的字符代码,或键的代码
事例
/* 键盘松开的时发生的事件 */
input.onkeyup = function(event){
/* keycode返回一个键盘码 */
if(event.keyCode == 13){
/* 只要是对象的属性,都可以通过点的方式去获取值 */
console.log(this.value)
}
窗口滚动onscroll
事例
<div class="nav" id="nav">导航</div>
<script>
/* onscroll 滚动事件 */
var nav = document.getElementById("nav")
window.onscroll = function(){
/* 获取滚动条距离顶部的高度 */
var scrollTop = document.documentElement.scrollTop;
/* 当滚动条距离顶部的高度达到300时候完全显示 */
var opacity = scrollTop/300;
if(opacity>1){
opacity = 1
}
nav.style.opacity = opacity;
nav.style.backgroundColor = "red"
}
</script>
onload
window.onload = function(){
var input = document.getElementById("input");
input.onchange = function(event){
console.log(this.value)
}
}
/*
onload 等DOM树以及图片相关资源加载完毕,再执行函数中的代码
*/
四、BOM
1.BOM的介绍
JavaScript基础分为三个部分:
- ECMAScript:JavaScript的语法标准。包括变量、表达式、运算符、函数、if语句、for语句等。
- DOM:文档对象模型,操作网页上的元素的API。比如让盒子移动、变色、轮播图等。
- BOM:浏览器对象模型,操作浏览器部分功能的API。比如让浏览器自动滚动。
BOM:Browser Object Model,浏览器对象模型。
BOM的结构图:
由上图可知:
window对象是bom的顶层对象,所有对象都是通过它延伸出来的,也可以成为window的子对象
dom是bom的一部分
window对象:
- window对象是JavaScript中的顶级对象。
- 全局变量、自定义函数也是window对象的属性和方法
- window对象下的属性和方法调用时,可以省略window
2.弹出系统对话框
比如alert(1)是window.alert(1)的简写
系统对话框有三种:alert(); //弹出警告框 confirm(); //弹出确认框,确定 返回true,取消 返回false prompt(); //弹出提示用户输入的对话框, 返回输入的内容
3.打开、关闭窗口
打开窗口
window.open(url,target,param);
/*url:要打开的地址
target:新窗口的位置,可以是 _blank、_self、_parent
param:新窗口的一些设置
返回值:新窗口的句柄
*/
关闭窗口
window.close();
4.setTimeout和setInterval
<script>
/* 超时调用 间隔一段时间,执行函数,且只执行一次 */
/* 异步 */
console.log(1)
setTimeout(function(){
console.log("a")
},1000)
console.log(2); //结果1 2 a;由于这个方法要1s时间故先跳过,最后执行
</script>
<script>
/* 间歇调用 间隔一段时间,执行函数 */
setInterval(function(){
console.log("b")
},3000)
</script>
<script>
var btn = document.getElementById("btn");
var timer = window.setInterval(function(){
console.log("a")
},3000)
/* 清除定时器
clearInterval()
*/
console.log(timer)
btn.onclick = function(){
clearInterval(timer)
}
</script>
5.BOM的内置对象
location对象
window.location可以简写成location。location相当于浏览器地址栏,可以将URL解析成独立的片段
location对象的属性:
- href:跳转
- hash 返回url中#后面的内容,包含#
- host 主机名,包括端口
- hostname 主机名
- pathname url中的路径部分
- protocol 协议 一般是http、https
- search 查询字符串
location.href属性举例:
有时候,当我们访问一个不存在的网页时,会提示5秒后自动跳转到指定页面,此时就可以用到location。
<script>
setTimeout(function () {
location.href = "http://www.baidu.com";
}, 5000);
</script>
navigator对象
window.navigator的一些属性可以获取客户端的一些信息
- userAgent:系统,浏览器
- platform:浏览器支持的系统,win/mac/linux
结果:console.log(navigator.userAgent); console.log(navigator.platform);
history对象
1、历史记录管理
2、后退:
- history.back()
- history.go(-1):0是刷新
3、前进:
- history.forward()
- history.go(1)
用的不多。因为浏览器中已经自带了这些功能的按钮
五、事件对象Event和冒泡
1.绑定事件的两种方式
方式一:onclick
<body>
<button>点我</button>
<script>
var btn = document.getElementsByTagName("button")[0];
//这种事件绑定的方法容易被层叠。
btn.onclick = function () {
console.log("事件1"); //被事件2覆盖
}
btn.onclick = function () {
console.log("事件2"); //控制台只显示事件2
}
</script>
</body>
方式二:addEventListener
addEventListener()里的参数:
- 参数1:事件名(注意,没有on)
- 参数2:事件名(执行函数)
参数3:false或者true(冒泡或者捕获) ```javascript
点击按钮后,上方代码的打印结果:
事件1 事件2
<a name="jdHBQ"></a> ### 2.事件冒泡和事件捕获  <a name="GkYV4"></a> #### 事件冒泡 **事件冒泡:即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点。**<br />通俗的将就是父元素和子元素绑定了相同的事件,子元素的事件执行,父元素的事件也会触发<br />点击子元素,会先弹出child,再弹出parent ```javascript parent.onclick = function(){ alert("parent") } child.onclick = function(){ alert("child") }
阻止事件冒泡: event.stopPropagation();
parent.onclick = function(event){ alert("parent") event.stopPropagation() } child.onclick = function(event){ alert("child") event.stopPropagation() }
事件捕获
事件捕获:不太具体的节点应该更早接收到事件,而具体的节点应该最后接收到事件。
点击子元素,会先弹出parent,再弹出childchild.addEventListener('click',function(){ alert("child") },true) parent.addEventListener('click',function(){ alert("parent") },true)