JavaScript

变量
<!-- IDEA 必须要先支持ES6 版本的JavaScript 'use strict' 严格检查模式,必须写在第一行!! --> <script> 'use strict'; // ES6 的JavaScript let 是定义局部变量 // const 是定义常量 let i = 1; const j = 1; </script>
var 王者荣耀 = "倔强青铜"; // 变量名是可以 以中文命名的,其实这个java 里也可以,只是一般不用,了解即可。。
console.log(王者荣耀); 倔强青铜 // 输出的值
字符串
// 转义 \
alert("12\n3"); // 这样输出就是换行的,相对应 \t 是等于Tab
// 多行编写,Tab键上面的 ` 键 var a = ` hello, 你好 `; console.log(a);
let i = "student"; console.log(i.length); // 取字符串长度
console.log(i[2]); // 字符串的字 可以通过下标获得 // 如果通过下标赋值,替换字符串中的某个字,会失败的 i[0] = 'A'; console.log(i); // 这个打印的结果还是 student console.log(i.toUpperCase()); // 字符串转大写 console.log(i.toLowerCase()); // 字符串转小写 console.log(i.indexOf("t")); // 查找字符串中t 的下标,输出为 1 // 截取字符串 console.log(i.substring(2)); // 如果填写一个下标,截取下标到后面的所有字符串 console.log(i.substring(2,4)); // 如果填写两个下标,截取下标到后面的第3个下标,第4个下标不算
比较运算符
= 赋值
== 类型不一样,值一样的话,照样为 true
=== 除非类型一样,值也一样,才为 true
NaN
* NaN === NaN 这个结果为 false 它六亲不认,连自己都不认
* isNaN(NaN) 这个结果为 true 这个是指定是否为 NaN
浮点数问题
console.log( (1/3) === (1-2/3) ); // 这个是false 1/3: 三分之一是个无限的0.333。。。循环的, 1- 2/3 :这个结果值是三分之一 // 尽量避免使用浮点数进行运算,存在精度问题 console.log( Math.abs( 1/3 - ( 1 - 2/3 ) ) < 0.000001 ); // 这个结果为 true
数组
var arr = [ 1,2,3,'hello',null,true ]; // 这种写法可读性好,推荐使用 JavaScript 的数组和 java 里的数组差距还是很大的,没有类型约束,如果查找数组下标越界,就会 undefined new Array( 1,2,3,'hello',null,true ); // 这种没有上面的方式好,不推荐使用
<script>
var arr = [1,2,3,4,5];
console.log(arr.length); // 数组长度
arr[0] = 0; // 数组可以通过下标替换里面的值
// 数组可以改变长度
arr.length = 3; // 数组长度赋值过小,就会丢失数据
arr.length = 10; // 数组长度赋值过大,多余的几个值都为 undefined
var a = [1,2,3,4,5,"1","2"];
console.log(a.indexOf(2)); // 通过数组里的值(2),获得下标索引
console.log(a.indexOf("2")); // 数字2 和 字符串2 是不一样的
// slice 截取数组数据
var i = arr.slice(2); // 返回下标 2 到最后的一个新数组
var i2 = arr.slice(2,5); // 和字符串截取的一样,都是有头无尾
arr.push("a,b"); // 数组尾部添加数据,a,b
arr.pop(); // 数组尾部末端的一个数据被删除
arr.unshift("a"); // 从头部添加一个数据
arr.shift(); // 从头部删除一个数据
arr.sort(); // 数组排序,从小到大
arr.reverse(); // 数组反转,从大到小排序
var j = arr.concat([3,2,1]); // concat() 并没有修改数组,只是返回一个新数组
arr.join("-"); // 数组中的数据之间都会有一个 - 连接着数据
// 多维数组
var x = [[1,2],[3,4],[5,6]];
console.log(x[1][0]); // 多维数组取值一样通过下标,想找具体的一个数组,再找数组里的值
</script>
对象
<script>
// 定义对象 属性之间用逗号隔开,最后一个属性不加逗号
var person = {
name:"wangbiao",
age:3,
score:0
}
console.log(person.name); // 获取对象属性的值
// 给对象属性赋值
person.name = "王彪"; // 这样,对象属性name的值就变了
person.sss; // 没有这个属性的值,undefined 未找到
delete person.name; // 通过delete 删除对象的属性
person.haha = "haha"; // 可以直接的这样添加一个属性
// 通过 in 判断属性是否属于某个对象
// js中所有的 键 都是字符串,对象是任意值
'age' in person; // 判断person对象里有没有in,返回true
'toString' in person; // toString 是父类的属性,返回值也是true
person.hasOwnProperty("age"); // true 判断age属性是否属于person对象
person.hasOwnProperty("toString"); // false toString属于父类里,不属于person对象自己的属性
</script>
Map 和 Set 以及迭代遍历
// Map: var map = new Map([["tom",100],["jack",90],["haha",10]]); var name = map.get("tom"); // 通过get获取map集合中的数据 console.log(name); // for in 是便利通过下标的,不是数组类型的集合最后用for of,Map 和 Set 都用for of for(let x of map){ // 通过for of 遍历Map中数据,用for in 是不行的!! console.log(x); } map.set("admin",123456); // 通过set方法给map集合添加数据 map.delete("tom"); // 删除一个数据,通过键 // Set: var set = new Set([1,2,3,3,2,1,2,3]); // Set 和java里一样的,可以去除重复的数据 for(let x of set){ // 通过for of 遍历Set中数据,用for in 是不行的!! console.log(x); } set.add(5); // 添加一个数据 set.delete(1); // 删除所有的1的数据,相同的数据都删除 console.log(set.has(3)); // 通过has 判断set里是否有3 这个值
函数 function
// 后端写法 function abc(i) { if (i < 5){ return 0; } else if (i > 5) { return 10; } } // 前端写法 var a = function (i) { if (i < 5){ return 0; } else if (i > 5) { return 10; } } // 两种写法是本意一样的 abc(15); // 通过函数名调用,比如这个abc 方法现在返回值是 10 a(10); // 参数问题 abc(20,30,5,6,7,8); // 就算给传多个参数,也不会报错,等于就只有的一个参数,结果为10 // 还能手动抛出异常 function x(i) { if (typeof x !== 'number'){ throw 'Not a Number'; // 如果出错,浏览器就会打印这句话 } // 比如调用时候,没有传参数,也是报错 if (i < 5){ return 0; } else if (i > 5) { return 10; } } // arguments: 代表传进来的所有的参数,是一个数组,方法的参数多传了,也会存在方法里面 function y(i) { for (let j = 0; j < arguments.length; j++) { console.log(arguments[j]); // 这样会把多传进来多余的参数也打印出来 } if (i < 5){ return 0; } else if (i > 5) { return 10; } } // 用arguments 的话,如果想用多余出来的参数进行操作,需要排除已有参数 // 可以用 rest 获取传入参数多余出来之外的所有参数 function aaa(a,b,...rest) { //这个是固定写法,rest在最后面,中间要加 ... console.log('a---'+a); console.log('b---'+b); console.log(rest); }
变量的作用域
function a() { var i = 1; i = i + 1; }
i = i + 2; // 这样会报错,调用失败,找不到 i
这两个函数使用相同的变量名,但是都在各个函数内部,所以可以用
// 这两个函数使用相同的变量名,但是都在各个函数内部,所以可以用 function a() { var i = 1; i = i + 1; } function b() { var i = 1; i = i + 1; }
内部可以访问外部,外部不能访问调用内部定义的变量
function a() { var x = 1; function b() { var y = x + 1; // 这个可以,内部可以访问外部 } var z = y + 1; // 这个就会报错,因为y 是在b 函数里面内部的 }
如果外部变量和内部变量定义的变量名一样,就近原则
function a() { var x = 1; function b() { var x = 'A'; console.log('inner'+x); // innerA } console.log('outer'+x); // outer1 }
一般最好把变量定义在函数里面的前面
function a() { var x = "x"+y; console.log(x); // 不会报错,因为下面定义了,但是y会找不到。如果把y 定义到x 前面,就正常能用,一般都是把变量定义在前面 var y = "y"; }
工作中可以自己定义唯一空间名字,减少window 的全局命名冲突
// 定义一个全局变量 var WangBiao = {}; // 定义全局变量 WangBiao.name = "wangbiao"; WangBiao.addNumber = function (a,b) { return a + b; } // 这样,每次都用自己定义的变量,减少window 的全局命名冲突
局部作用域
function a() { // 局部定义最好都是用 let for (let i = 0; i < 10, i++){ console.log(i); } // 出了for 循环就报错找不到 i console.log(i); }
定义常量
const PI = 3.14; // const 是定义常量的,不可以再改变 PI = 123; // 如果改变,就会报错 类型错误
方法定义 调用
var biao = { name:'wangbiao', birth:1994, // 把age 定义成一个计算年龄的方法 age:function () { // 今年 - 出生年 var now = new Date().getFullYear(); // 获得当前时间年份 return now - this.birth; } } // 方法调用 biao.name // 调用属性 biao.age() // 调用方法一定要带括号
调用引用的方法一:
function getAge() { // 今年 - 出生年 var now = new Date().getFullYear(); // 获得当前时间年份 return now - this.birth; } var biao = { name: 'wangbiao', birth: 1994, age: getAge // 不要带括号,不然是 NaN } biao.age() // 调用方法切记带括号
调用方法二:
function getAge() { // 今年 - 出生年 var now = new Date().getFullYear(); // 获得当前时间年份 return now - this.birth; } var biao = { name: 'wangbiao', birth: 1994, age: getAge // 不要带括号,不然是 NaN } // 区分好 括号 getAge.apply(biao,[]); // 这个方法指向 biao,参数为空
以上两种方法,一个是主动调用,一个是被动调用
Date
时间戳:全世界统一的,从1970年的1月1日00:00:00 时间 至今的毫秒数
var now = new Date(); // 获得当前时间 now.getFullYear(); // 当前时间年 now.getMonth(); // 当前时间月 月份是从0-11代表的 now.getDate(); // 当前时间日 now.getDay(); // 当前时间周 now.getHours(); // 当前时间时 now.getMinutes(); // 当前时间分 now.getSeconds(); // 当前时间秒 now.getTime(); // 当前时间的时间戳 now.toLocaleString(); // 获取本地时间
js-面向对象
原型继承 所有的对象都是循环继承的原型链!
__proto__ 这个两边是两个下划线
每个对象都有原型,只要一个对象具备另一个对象的原型,就又这个对象的属性
var user = { name:"wangbiao", age:3, run:function () { console.log(this.name+"跑步ing。。。"); } }; var xiaoming = { name:'xiaoming' }; var Bird = { fly:function () { console.log(this.name+"飞到天上。。。"); } } xiaoming.__proto__ = user; // 这个原型是两个下划线 xiaoming.__proto__ = Bird; // 这样,小明就有了鸟会飞的属性
切记调用函数时,加上括号!!
class继承
class Student { constructor(name){ this.name = name; } hello(){ alert("hello"); } } class XiaoXueSheng extends Student{ constructor(name,grade){ super(name); this.grade = grade; } myGrade(){ alert("我是一名小学生"); } } var biao = new Student("wangbiao"); // 新定义的biao 就具备了Student的属性 hello() 这个方法 var xiaohong = new XiaoXueSheng("xiaohong"); // 这样,小红就具备了hello() 和 myGrade() 两个方法的属性
BOM 浏览器元素
window 可以点 . 出来非常多的方法
比如:
window.alert(1)
window.innerHeight // 浏览器内部高度
window.innerWidth // 浏览器内部宽度
window.outerHeight // 浏览器外部高度
window.outerWidth // 浏览器外部宽度
screen: 获取屏幕
screen.width
1920
screen.height
1080
location:代表当前页面的url 信息
location 里面包含了很多信息
location
Location {href: "chrome-search://local-ntp/local-ntp.html", ancestorOrigins: DOMStringList, origin: "chrome-search://local-ntp", protocol: "chrome-search:", host: "local-ntp", …}ancestorOrigins: DOMStringList {length: 0}origin: "chrome-search://local-ntp"protocol: "chrome-search:"host: "local-ntp"hostname: "local-ntp"port: ""pathname: "/local-ntp.html"search: ""hash: ""href: "chrome-search://local-ntp/local-ntp.html"assign: ƒ assign()reload: ƒ reload()toString: ƒ toString()replace: ƒ replace()valueOf: ƒ valueOf()Symbol(Symbol.toPrimitive): undefined__proto__: Location
host href protocol reload 都很重要
location.assign("XXX网页") 如果把这个给改了,所有访问人家的网页都会跳到你自己的XXX网页了
document 代表当前页面,DOM文档树
比如:
document.title // 获取页面标题
document.title='wangbiao' // 这个就把标题给改了
document.getElementById("XXX"); // 通过id 找到标签
document.cookie // 还能获得cookie 呢,很多恶意病毒都是根据这个得到了别人的cookie ,给劫持了
cookie: httpOnly // 通过这个设置cookie 为只读的,这样就安全了
history 代表浏览器的历史记录
history.back() // 后退
history.forward() // 前进
很多人开发为了偷懒,就直接前进,后退,从而放回首页什么的,这样其实不好,还是根据controller 写请求比较好
DOM 浏览器网页就是一个DOM树形结构
我们通常对一个DOM 节点进行增删改 遍历,想要操作DOM 节点,就要先获得这个节点
获得节点
var h = document.getElementsByTagName('h1'); // 通过节点类型名称获得节点 var p = document.getElementById("p1"); // 通过id 获得节点 var c = document.getElementsByClassName("c"); // 通过class获得节点 var childrens = h.children; // 获得上面定义的h 这个节点的下面所有子节点; h.firstChild; // 下面的第一个子节点 h.lastChild; // 下面的最后的一个子节点
更新节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="id1">
abc
</div>
</body>
</html>
<script>
var id1 = document.getElementById("id1");
id1.innerText = '456'; // 修改文本的值
id1.innerHTML = '<strong>123</strong>'; // 通过HTML修改可以解析HTML标签
id1.style.color = "red";
id1.style.fontSize = "100px";
id1.style.padding = "50px";
</script>
切记js 代码放在页面标签后面,js 代码才能先获得标签节点 再执行js 代码,不然会报错 未找到节点,为空
删除节点 要先获得父 节点,再通过父节点删除自己
<div id="id1">
<p id="p1">abc</p>
</div>
<script>
var id1 = document.getElementById("id1");
var p1 = document.getElementById("p1");
id1.removeChild(p1);
</script>
如果不知道父类节点是哪个。。。
直接子节点去点 . parentElement ,就得到的是父节点
var p1 = document.getElementById("p1"); var father = p1.parentElement; father.removeChild(p1);
还可以通过找子节点下标方式删除
var p1 = document.getElementById("p1"); var father = p1.parentElement; father.removeChild( father.children[0] );
切记,删除是动态的,如果是删除多个标签,子节点下标也是会发生变化的
创建 并 插入节点
如果用innerHTML 增加一个元素节点,如果这个DOM 节点已经存在,就不能这样干了,因为会覆盖!!
追加节点:这种办法等于是外面写好了一个标签,然后加在div 里面了
<p id="js">JavaScript</p>
<div id="list">
<p id="se">javaSE</p>
<p id="ee">javaEE</p>
<p id="me">javaME</p>
</div>
var js = document.getElementById("js"); var list = document.getElementById("list"); list.appendChild(js);
这样,就把 <p id="js">JavaScript</p> 给加在了div 里面的最后一个节点了
就是等于这样:
<div id="list">
<p id="se">javaSE</p>
<p id="ee">javaEE</p>
<p id="me">javaME</p>
<p id="js">JavaScript</p>
</div>
方法二:创建一个标签,并且可以各种操作
<div id="list">
<p id="se">javaSE</p>
<p id="ee">javaEE</p>
<p id="me">javaME</p>
</div>
var newP = document.createElement('p'); // 新建一个节点 p 标签 newP.id = 'newP'; newP.innerText = "hello"; list.appendChild(newP);
这个就等于
<p id="newP">
hello
</p>
第二种方法可以说万能的,什么标签都能加,比如新建一个script 标签
var myScript = document.createElement('script'); myScript.setAttribute('type','text/javascript'); // 类似的比如给 标签添加样式
可以通过有这一种方法指定插入节点位置:insertBefore( , );
<div id="list">
<p id="se">javaSE</p>
<p id="ee">javaEE</p>
<p id="me">javaME</p>
</div>
var se = document.getElementById('se'); var ee = document.getElementById('ee'); var list = document.getElementById('list'); // list是父节点,传入的参数意思是,把ee 放在了se 前面 list.insertBefore(ee,se);
获得 设置 表单的值
文本框 text
下拉框 <select>
单选框 radio
多选框 checkbox
隐藏域 hidden
密码框 password
等等。。。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form> <p> <span>用户名</span><input id="username"> </p> <p> <span>性别</span> <input type="radio" name="sex" value="man" id="boy">男 <input type="radio" name="sex" value="woman" id="girl">女 </p> </form> <script> var inputText = document.getElementById('username'); inputText.value(); // 得到输入框的值 inputText.value = '123'; // 赋值,修改输入框的值 var boy_radio = document.getElementById('boy'); var girl_radio = document.getElementById('boy'); // 对多选框或单选框。。固定的值,boy_radio.value 只能取到当前的值,如果想赋值,利用checked 属性 boy_radio.checked = true; // 给它赋值为true 就等于选择了 男 </script> </body> </html>
required 加入这个标签属性,就为必填项!!
表单提交验证
用户名 密码 以及 MD5验证密码
<form action="" method="post"> <p> <span>用户名</span><input id="username" name="username" required> </p> <p> <span>密码</span><input id="password" type="password" name="password"> </p> <button type="button" onclick="aaa()">提交</button> </form> <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script> <script> function aaa(){ var name = document.getElementById('username'); var pwd = document.getElementById('password'); // MD5 算法,要先引入上面的MD5 在线工具类 pwd.value = md5(pwd.value); return true; } </script>
这样其实还是不安全,因为前端人员都知道浏览器通过密码的 name 属性是password,想要安全再加一个隐藏域,这样前端也看不见
<!--onsubmit 绑定一个提交检验的函数,true就提交成功,false就失败--> <form action="https://www.baidu.com/" method="post" onsubmit="return aaa()"> <p> <span>用户名</span><input id="username" name="username" required> </p> <p> <span>密码</span><input id="input-password" type="password"> </p> <!--隐藏域,这样前端也看不见,更安全--> <input type="hidden" name="password" id="md5-password"> <button type="submit">提交</button> </form> <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script> <script> function aaa(){ var name = document.getElementById('username'); var pwd = document.getElementById('password'); var md5pwd = document.getElementById('md5-password'); md5pwd.value = md5(pwd.value); // 把用户输入过的值md5 加密以后,再赋值给隐藏域,隐藏域的name属性为 password return true; } </script>
这种方法是提交表单,提交用submit 提交form 表单,然后form 标签里的onsubmit 也要return,aaa() 这个方法也要return
jQuery公式
引入jQuery 库的方式,第一种是常用的引入本地的,
第二种是引入线上的 <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--引入cdn 线上的jQuery库--> <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> </head> <body> <a href="#" id="jqueryTest">点击</a> <script> $("#jqueryTest").click(function () { alert("hello,jQuery"); }) </script> </body> </html>
jQuery 选择器
$("p").click(); // 标签选择器,选择P 标签
$("#id1").click(); // id选择器,选择id 是id1 的标签
$(".class1").click(); // 类选择器,选择class 是class1 的标签
jQuery 事件
鼠标事件,键盘事件,其他事件。。
mousedown() // 鼠标按下
mouseleave() // 鼠标离开
mousemove() // 鼠标移动
mouseover() // 鼠标弹起
等等。。。很多事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!--引入cdn 线上的jQuery库--> <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <style> #divMove{ width: 500px; height: 500px; border: 1px solid red; } </style> </head> <body> mouse: <span id="mouseMove"></span> <div id="divMove"> 鼠标放在这里 </div> <script> $(function () { // 鼠标移动事件 $("#divMove").mousemove(function (e) { $("#mouseMove").text('x'+e.pageX + 'y'+e.pageY); }) }); </script> </body> </html>
jQuery 操作DOM
节点文本操作
<ul id="test-ul"> <li class="js">JavaScript</li> <li name="python">Python</li> </ul> <script> $(".js").text(); // 获取值 $(".js").text("java"); // 修改标签里的值 $(".js").html(); // 获取值 $(".js").html('<strong>123</strong>'); // 修改标签里的值 // 通过ul 标签获取下面的li 标签的值 $("#test-ul li[name=python]").text(); // 获取值 $("#test-ul li[name=python]").text("PHP"); // 修改标签里的值 </script>
CSS 操作
<ul id="test-ul"> <li class="js">JavaScript</li> <li name="python">Python</li> </ul> <script> $(".js").css("color","red"); // 这样页面字体就变红色 </script>
元素的显示 和 隐藏 toggle 可以显示隐藏来回切换的
<ul id="test-ul"> <li class="js">JavaScript</li> <li name="python">Python</li> </ul> <script> // 通过ul 选择下面子节点li // 当然,可以直接 $(".js").hide(); $("#test-ul li[name=python]").hide(); // 隐藏 $("#test-ul li[class=js]").show(); // 显示 $(".js").toggle(); // 这个可以显示和隐藏来回轮流切换的 </script>
娱乐测试:
$(window).width(); // 获取浏览器宽度 $(window).height(); // 获取浏览器高度

浙公网安备 33010602011771号