目录
0x00JavaScript的背景及知识结构
1.什么是javascript? 轻量级编程语言,html+css属于设计类的语言。javascript借鉴了java(update2019.4.24:js和Java没有任何关系,livescript就是为了蹭java的热度,从而改名为JavaScript),成为了一种能够在浏览器上运行的脚本。是目前最流行的脚本。可以插入到html页面中,基本上所有的浏览器中都可以执行(只要有JavaScript解释器即可)。所以,JavaScript也可以运行在服务器,手机端。JavaScript容易学,门槛低,精通则需要多练习。
2.JavaScript能干什么? html+CSS负责网页的内容 JavaScript负责网页的行为,可以改进设计,实现动态效果。可以验证表单,还可以检查浏览器。可以创建cookies。
总之,可以实现和用户的交互。(交互:交流互动)
3.JavaScript是由什么构成的>>>如何学习JavaScript?
构成:
ECMAscript:解释器,负责逻辑处理部分,是js的标准
文档对象模型(DOM):负责dom操作部分,修改html元素---->库 API。W3C是DOM的标准
DOM 1级:
DOM核心
DOM HTML
DOM 2级:在DOM1级的基础上扩充了鼠标和用户界面事件、范围、遍历等细分模块,而且通过对象接口增加了对CSS的的支持
DOM 3级:
浏览器对象模型BOM:获取浏览器的信息,缺乏标准
0x01 导入js的两种方式
方式1:包含外部文件
注意:
1.外本文件一般是.js后缀,但是浏览器是不会检查包含js代码的文件的后缀名的。因为,这样使用jsp、php、asp动态生成的js代码就可以作为外部文件被包含。但是注意,如果不使用js后缀的文件,服务器发给浏览器的头消息中的MIME类型必须和文件类型匹配。
2.如果包含外部文件的同时还包含嵌入式js代码,嵌入式js代码将被忽略。
3.defer属性:表示脚本立即会被下载,但是会被延迟到整个页面DOM树解析完毕后再运行。
注意:
1.defer属性只对外部脚本文件有效,如果你给嵌入式脚本设置了defer属性,那么这个属性将被忽略
2.设置为defer属性的scirpt标签并不一定是按照顺序执行的,因此最好保证scirpt标签之间互不依赖。
4.async:表示立即下载脚本,但是并不阻塞页面中的其他操作(下载其他资源或者等待加载其他脚本),
注意:
1.该属性只对外部脚本文件有效
2.标记为async的脚本并不保证先后顺序执行
3.xhtml文档中要把 async属性设置成async=“async”;
注意:script标签中的language属性已经被淘汰,因为VBscript已经逐步被淘汰了。大多数浏览器都会忽略languag属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>基本语法</title>
<script src="1.js"></script>
<script defer="defer" src="2.js"></script>
<script async src="2.js"></script>
<script defer="defer" src="2.js"></script>
</head>
<body>
</body>
</html>
scirpt和img标签的src属性都可以指向当前html页面所在域之外的某个域种的完整的url,我觉得这一点给挂马提供了极大的方便,浏览器的同源策略限制了iframe的src属性,但是对img和script的src属性没有做任何限制。一旦一个页面存在xss漏洞,那么我们完全可以通过xss来注入DOM操作来读写script的src属性或者img的src属性,从而达到挂马的目的,所以web开发人员应该注意防范这一点。
var script=document.getElementsByTagName("script");
for(var i=0;i<script.length;i++){
script[i].setAttribute("src","网络上某个木马地址");
}
方式2:嵌入式代码
注意:嵌入式代码中的任何地方不可以包含</script>,因为当浏览器遇到字符串“</script>”,浏览器就会认为它是script的结束标签。通过转义字符<\/script>可以解决这个问题,这样浏览器就会它看成字符串“</script>”。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>基本语法</title>
<script>alert("Hello world2")</script>
</head>
<body>
</body>
</html>
xhtml中嵌入式script中如果包含小于号(<)则会被当成一个新标签的开始,如果这个小于号之后跟了空格,因为新标签的开始之后不能跟空格,所以会产生一个语法错误。
解决方法:
1.用HTML实体(<;)来代替代码中所有的小于号
2.用<![CDATA[js代码]]>来包含整个嵌入式js代码。CDATA片段中任何代码都不会被当成标签。
0x02 js导入的最佳位置
建议将script标签写在页面的最后,body结束标签之前,这样做有三方面的原因:
这样DOM树就解析完毕了,可以对任何DOM节点进行DOM操作
如果js放在前面并且js代码很多的话,会阻碍页面html代码的呈现,这样在下载解析js的大段时间里,用户看到的只是空白页面,这将是很差的用户体验。js代码放在后面,先给用户呈现html内容能让用户感觉页面打开速度变快了
也可以将js代码放前面,通过window.onload达到js放html后面的效果。
window.onload的作用是当页面加载完成(DOM树已经生成完毕后)自动触发该事件
一个页面应该只有一个window.onload事件,因为如果写多个的话会覆盖,只执行最后一个。
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
#tim{
width:200px;
height:200px;
border:1px solid green;
margin:0 auto;
}
</style>
<script type="text/javascript">
window.onload=function(){
document.getElementById("tim").style.background='red';
alert(1);
}
window.onload=function(){
document.getElementById("tim").style.background='red';
alert(2);
}
window.onload=function(){
document.getElementById("tim").style.background='red';
alert(3);
}
</script>
</head>
<body>
<div id="tim" class='new'>
</div>
</body>
</html>
文档模式:
混杂模式:如果没有DOCTYPE声明,那么默认为混杂模式,不同浏览器在混杂模式的行为差异很大
标准模式:标准模式和准标准模式的几乎一样,
准标准模式
如果浏览器不支持js脚本或者js脚本被有意禁用,浏览器都会显示<noscript></noscript>标签中的内容,并且这个标签中的内容将被生成成html代码解析。除此之外的其他情况,浏览器都不会显示noscript的内容。
语法:
所有语句都是用字母,数字,特殊符号组成的命令
对字母的大小写是敏感的。
以分号来区分命令
启用严格模式:“use strict”在顶部添加,则整个脚本都会启用严格模式,在函数定义的内部的顶部添加,则函数体中启用严格模式。这个指令不是一个字符串,而是一个编译指令,告诉js引擎切换到严格模式。
注释:
单行注释://
多行注释:/* */
0x03 js输出方式和调试方式
1.alert("输出内容") 弹出警告窗
2.console.log("输出内容") 在控制台中输出(按F12查看控制台)
3.innerHTML和innerText:
设置标签的内容
innerHTML设置的内容中的标签会被解析,innerText则不会,直接作为字符串输出;
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
window.onload=function(){
document.getElementById("tim").innerHTML='<a href="https://www.baidu.com">我是tim盒子的内容我被注入进来了</a>';
document.getElementById("bob").innerText ='<a href="https://www.baidu.com">我是bob盒子的内容我被注入进来了</a>';
}
</script>
</head>
<body>
<div id="tim" class='new'></div>
<div id="bob"></div>
</body>
</html>
4.document.write("输出内容")
如果在整个DOM已经生成完毕之后,通过一些事件来触发它的话。将会重写整个html页面。函数的传参即为新的html页面中body元素中的内容。
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
window.onload=function(){
document.getElementById('rewrite').onclick=function(){
document.write("我是重写之后的内容");
}
}
</script>
</head>
<body>
<div id='rewrite'>重写页面</div>
</body>
</html>
0x04 值和变量
值:直接量
数字:整数和浮点数,
八进制以0开头,且数字必须都不超过8,如果数字超过了8则会被当成10进制解析。
十六进制必须以0x开头
浮点型的加减运算存在误差,不要做浮点型加减运算的比较操作,会坑死你的。
ecmascript能表示的最小数值保存在Number.MIN_VALUE中,最大值保存在Number.MAX_VALUE中。如果一个数超过了这个范围,那么就会被自动转化成Infinity正无穷或者-Infinity.这个值是不能参与运算的。
判断一个数是否在最大最小范围内,用isFinite()函数,是则返回true。
NaN(Not a Number):任何本来应该返回数字的操作,如果没有返回数字,都会返回NaN,例如:任何数值除以非数值都会返回NaN。NaN和任何值都不相等,包括自己。
将非数值转化成数值:
Number():可以把任意类型的数据转化为数字。转化规则见p30
parseInt():将字符串转化为十进制整数。
该函数会忽略字符串前面的空格,从第一个非空格字符开始转换,如果第一个非空格字符不是数字,那么直接返回NaN,如果第一个非空格字符是数字,则会解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符为止。
0x开头的字符串会被当做十六进制的数字 并强转为 10进制整数。
以0开头的字符串会被当做8进制的数字 并强转为 10进制整数。
字符串:单引号和双引号里面的东西都是字符串
布尔值:因为js是严格区分大小写的,所以只有小写的true和false才是布尔值,而大写的True和False不是布尔值,对任何数据调用Boolean()函数会将该数据转化成布尔值,详情查看js高级程序设计第三版p27页。
变量:如果未经过初始化,则变量的值为undefined,
声明变量:
var x;//声明一个变量
x="hello world";
var y="hello pig";
var a,b,c,d;
var d=1,h=2,z=3;
//如果变量省略var操作符,那么这个变量就成了全局变量。
/*
变量名必须是字母和数字,可以有$_
变量开始最好是字母或者_
变量对大小写敏感
*/
console.log(y);
注意:js执行时先定义再执行,例如
console.log(a);//undefined
var a='tim';
//上面两行代码等同于下面的代码,因为js执行是先定义再执行
var a;
console.log(a);
a='tim';
0x05基础数据类型:(面试重点)
面试题1:js的基础数据类型有什么?
- 字符串string
- 数字(整型浮点型) number
- 布尔 boolean
- null 空对象
- undefined未定义
复杂数据类型:
数组:array
对象:object
0x06检测数据类型的两种方法:
1.typeof()
typeof null会返回object,因为null被认为是一个空的对象指针。对未被初始化或者未被声明的变量typeof返回值也是undefined
因为undefined的值派生自null值,所以ecma-262规定 null==undefined
2.Object.prototype.toString.call('数据') //鉴别复杂数据类型、引用数据类型
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
console.log(typeof('hello world'));
console.log(typeof(111));
console.log(typeof(null));
console.log(typeof(undefined));
console.log(typeof(true));
console.log(typeof({}));
console.log(Object.prototype.toString.call({}));
console.log(typeof([]));
console.log(Object.prototype.toString.call([]));
</script>
</body>
</html>
0x06 数据类型的转换
显式类型转化(强转):
Number()
parseInt();
parseFloat();
String();
toString();
Boolean();
//将任意类型强制转化成数字:Number( )
var a="12222";
var b=Number(a);
a.toString();//将a转换成字符串
隐式转换:
- 操作符或者语句进行运算时
- if while比较里面也会进行隐式转换。
加号:如果两边有一边有字符串,则两边都当字符串处理。没有字符串则按数字处理
布尔值如果是字符串,则按字符串处理,如果不是,则true=1 false=0;
1+"a"="1"+"a"="1a"
1+false=1+0=1;
false+"a"="falsea";
减乘除取余都是转化成数字
1-"1"=1-1=0
1-"A"=NaN //not a number
==和===:
== 两端只要值一样(类型不一样的两端,其实发生了隐式类型转化)就返回true
===两端不仅需要值一样,类型也要一样,才返回true。
0x07 创建复杂数据类型数组和对象
数组创建:
1.直接创建:
var arr =[1,2];
arr.length返回数组的长度
2.利用构造函数创建:
var arr1 = new Array(); 创建一个空的数组
var arr2 = new Array(1,2,3);创建数组并初始化
var arr3 = new Array(10); 创建一个长度为10的数组。
var a=[60,61,62];//数组
a[0]==60;
a[1]==61;
var b=[0,"string",ture]//仍然正确
创建对象:
1.直接创建
var e={}//创建一个空对象
//自定义的对象
var e={
"a1":60,
"a2":61,
"a3":62
};
alert(e.a1);
e.a2;
e.a3;
var f={
0:60,
1:52,
2:42
};
f[0];
f[1];
2.利用构造函数创建
var obj = new Object();
0x08 第一个js脚本的编写
需求:鼠标移入div背景颜色变成红色,鼠标移出,背景颜色变回白色
第一步,我们要知道鼠标移入事件和鼠标移出事件
鼠标移入事件 onmouseover
鼠标移出事件 onmouseout
第二步,我们要找到需要改变的div元素
我们通过id就可以找到我们要改变的div
第三步,我们要修改我们的css属性
其中点就是‘的’的意思
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
#tim{
width:200px;
height:200px;
border:1px solid green;
margin:0 auto;
}
</style>
</head>
<body>
<div id="tim" onmouseover='tim.style.background="red"' onmouseout='tim.style.background="green"'>
</div>
</body>
</html>
0x09 流程控制
1.if 、else if、else
2.三元运算符 条件?成立执行:不成立执行
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
var b = 10;
b == 10?console.log('成立'):console.log('不成立');
var a = (b>0)?100:200;
console.log(a);
</script>
</body>
</html>
3.switch case
0x0A 四种循环
1.while
2.do while
3.for(初始;判断;迭代)
4.for in 一般用来循环对象
将对象中键值对的键循环赋值给in之前的变量。
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
var obj = {name:'xiaoming',age:21,school:'xdu'};
for(o in obj){
console.log(o);//name age school
console.log(obj[o]);//xiaoming 21 xdu
//console.log(obj.o);//错误写法,因为o是变量所以必须采用中括号写法
}
</script>
</body>
</html>
0x0B js判断里什么是真什么是假
真:除了假都是真
假:false 0 空字符串 null undefined NaN
0x0C js逻辑运算符
&& || !