快速入门

引入Javascript

  1. 内部标签
<script>
//JavaScript代码(单行注释)
/*
*多行注释
*JavaScript严格区分大小写
*/
alert('Hello');
</script>
  1. 外部引入
<script src="abc.js"></script>

基本语法入门

  1. 定义变量:数据类型 变量名 = 值;
    var num = 1;(JavaScript里面的数据类型一律为var)
  2. 条件控制
    if-else 语句,和Java里一样

tips:浏览器必备调试JavaScript代码须知

  • 在浏览器控制台Console直接输入JavaScript代码查看错误
  • console.log();在浏览器控制台打印想要检查的部分
  • 在浏览器Source界面下可以添加断点来检查代码

数据类型

数值、文本、图形、音频、视频…
js不区分整数和小数

  • number
    浮点数运算会产生精度丢失
  • 字符串
  • 布尔值
  • 逻辑运算 && || !
  • 比较运算符 (=== 绝对等于,值一样,类型也一样才为true)
    须知:(NaN为非数值型值)
    • NaN===NaN,这个值与所有数值都不相等,包括自己
    • 只能通过isNaN(NaN)来判断这个数是否是NaN
  • null 和 undefined
  • 数组()
//为了保证代码的可读性,建议使用[]
var arr = [1,2,3,'Hello',null,true];
//如果取数组元素越界了不会报错,而是显示undefined
  • 对象
    对象用大括号{},数组用中括号[ ]
    每个属性之间用逗号隔开,最后一个不用
<script>
	var person = {
		name : "Matilda",
		age : 20,
		tags : ['java','web','js','...']
	}
</script>

严格检查模式strict

<script>
	<!--
	前提:需要IDEA支持ES6语法
	预防JavaScriptdd 随意性产生的一些问题
	必须写在JavaScript第一行
	局部变量建议用let去定义
	-->
	'use strict';
	// i = 1; 不加strict 可以正常使用,是个全局变量,会存在一些问题
	//加了let定义之后变成局部变量,用strict检查更严谨
	let i = 1;
	
</script>

数据类型

字符串

  1. 正常字符串用 单引号/双引号包裹
  2. 转义字符 \
  3. ES6中支持:多行字符串编写
<script>
	// `` 这个是单引号,是tab键上面一个,一般叫piao(飘)
	var str = `
		你好
		Hello
		Bonjour
		`
</script>
  1. 模板字符串
  2. 字符串长度
  3. 字符串不可变
  4. 大小写转换
  5. 获取下标
  6. 截取字符串 substring
<script>
	let name = 'Matilda';
	let age = 20;
	//用piao
	let msg = `你好呀,${name}`
	//字符串长度
	console.log(name.length);
	//转换大小写
	console.log(name.toUpperCase());
	//获取下标
	console.log(name.indexOf('t'));
	//截取字符串
	console.log(name.substring(1));//从下标 1 截取到末尾
    console.log(name.substring(1,3));//从下标1 截取到下标 2,左闭右开区间
</script>

数组

JavaScript中数组可以包含各种类型的数据

var arr = [1,2,3,4,5,'Matilda',null]
  1. 长度

     arr.length
     注意:假如给arr.length赋值,数组的大小会发生改变
     			多出来的空间为undifine,如果赋值过小,元素会丢失。
    
  2. indexof

     arr.indexof(2);
     通过元素获得下标
    
  3. slice () 截取数组中的一部分,
    返回一个新的数组,类似于String中的substring

     arr.slice(2);//截取下标2开始到末尾
     arr.slice(1,5);//截取下标1到5之间的元素;左闭右开区间
    
  4. push() / pop() 尾部

     arr.push('a','b');//在数组末尾压入这两个元素
     arr.pop('a');//将元素 b 从数组尾部弹出
    
  5. unshift() / shift() 头部

     arr.unshift('a','b');//在数组头部压入这两个元素
     arr.shift('a');//将元素 b 从数组头部弹出
    
  6. 排序 sort()

     arr.sort();//默认升序
    
  7. 元素反转 reverse()

     arr.reverse();
    
  8. 数组拼接 concat()

     arr.concat([1,2,3]);
     注:只是拼接了一下,返回了一个新数组,原数组arr并没有改变。
    
  9. 连接符 join

     打印拼接数组,使用特定的字符串连接
     arr.join('-');
    
  10. 多维数组

    arr = [[1,2],[3,4],[5,6]];
    arr[1][1];//4
    

对象

若干个键值对
注:JavaScript中所有的键都是字符串,值是任意类型。

var 对象名 = {
	属性名:属性值,
	属性名:属性值,
	属性名:属性值
}

var person = {
	name: 'Matilda',
	age: 20,
	sex: 'Male'
}

  1. 对象赋值

     person.name = '输入自己想要的值';
     直接改
    
  2. 使用一个不存在的属性,不会报错,显示undefined

     person.boy;//undefined
    
  3. 动态删减对象属性

     delete person.name
    
  4. 动态的添加属性

     person.boy = 'boy'
    
  5. 判断属性值是否存在某对象中

     'age' in person
     //父类的值也能判断
     'toString' in person
    
  6. 判断一个属性是否是这个对象自身拥有的hasOwnProperty()

    person.hasOwnProperty('age')
    

流程控制

  1. if 判断

  2. while 循环

  3. for 循环

     for(let i = 0; i < 100; i++){}
     ES6中局部变量用let,ES5用var
    
  4. 遍历数组 forEach 循环

     var arr = [1,23,4,5,6,7,8];
     //第一种 :es5.1特性
     arr.forEach(function(value) {
     	console.log(value);
     })
    
     //第二种:这里的num为数组元素的下标(不建议使用)
     for (var num in arr) {
     	console.log(age[num]);
     }
     
     //第三种:这里的num为数组元素
     for (var num of arr) {
     	console.log(num);
     }
    

Map 和 Set

ES6新特性

  • Map:
<script>
        let map = new Map([['Matilda',100],['Leon',90],['Mike',80]]);
        let score = map.get('Matilda');
        console.log(score);

		//添加键值对
        map.set('Lucy',60);
        //删除
        map.delete('Matilda');
</script>
  • Set:无序不重复的集合
<script>
	let set = new Set([11,2,3,,4,6]);
        set.add(5);
        set.delete(5);
        //判断是否存在某元素
        console.log(set.has(5));
</script>
  • 遍历 Map/Set :iterator
<script>
	//遍历Map
	for (let value of map) {
		console.log(value);
	}
	
	//遍历Set
	for (let value of set) {
		console.log(value);
	}
</script>

函数及面向对象

定义函数

定义方式一

绝对值函数:

function abs (x) {
	if (x >= 0) {
		return x;
	}
	else {
		return -x;
	}	
}

如果没有通过 return 结束函数,函数会返回undefined

定义方式二

匿名函数

//匿名函数
var abs = function (x) {
	if (x >= 0) {
		return x;
	}
	else {
		return -x;
	}	
}

调用函数

	abs(10);//10
	abs(-10);//10

提问:JavaScript可以传递任意个参数,也可以不传递参数
参数是否存在?
如何规避?

var abs = function (x) {
	//手动抛出异常
	if(typeof x != 'number') {
		throw 'Not a Number';
	}
	
	if (x >= 0) {
		return x;
	}
	else {
		return -x;
	}	
}

arguments

代表传递进来的所有参数是一个数组
举个栗子:
var abs = function (x) {
	for (var i = 0; i < arguements.length; i++) {
		console.log(arguements[i]);
	}
	
	if (x >= 0) {
		return x;
	}
	else {
		return -x;
	}	
}

rest

ES6 新特性:获取除了已经定义了的参数以外的所有参数

	以前要遍历其他的参数:
//当只有一个参数时
for (var i = 1; i < arguements.length; i++) {
		console.log(arguements[i]);
	}
	现在:
var abs = function (x,...rest) {
	console.log(rest);
}

变量的作用域

  1. 在JavaScript中,var定义的变量是有作用域的。
    在函数体内部定义的变量,在函数体外面是不可使用的。

  2. 两个不同的函数内可以拥有相同的变量名

  3. 函数嵌套时,里面的函数可以使用外面函数的变量,反之不行,同级也不行

  4. 函数嵌套时,内部和外部函数的变量名重名,在使用的时候会有一个双亲委派机制,在变量被调用的地方会先在自身的函数体中寻找有无定义该变量,有则用,没有的话则向外部查找直到找到就用,最终会找到 window 下,后面有解释。

  5. 变量的定义尽量都要放在最开头,这是一种规范

function add (a,b) {
	//1. 
	//函数体内定义sum
	var sum = a + b;
}

//函数体外不能使用
console.log(sum);

//2.
function add2 (a,b) {
	var sum = a + b;
}

//3. 
function fun() {
	var a = 1;
	function fun2() {
		var b = a + 1;
		
	}
	function fun3() {
		var z = b + 1;
		var a = 'A';
		console.log('inner' + a);//innerA
	}
	console.log('outer' + a);//outer1
}

全局函数

全局变量

<script>
	var num = 1;
	function fun() {
		console.log(num);
	}
	
	console.log(num);
</script>

全局对象 window

alert() 这个函数本身也是一个 window 下的变量(前面写过可以把函数赋给一个变量)

<script>
	var warning = 'warning';
	//window.alert();
	alert(warning);
	alert(window.warning);

	//可以将alert这个方法再赋值给其他变量
	var new_alert = window.alert;	
</script>

规范

由于所有的全局变量都会绑定到 window 上。如果不同的 js 文件使用了相同的全局变量名,则会产生冲突。那么如何减少冲突呢?
解:把自己的代码全部放在自己定义的wei’yi空间名字中,降低全局命名冲突问题。

//定义自己的唯一全局变量
var MatildaDemo = {};

//定义全局变量
MatildaDemo.name = 'Matilda';
MatildaDemo.add = function(a,b) {
	return a + b;
}

局部作用域 let

//问题: i 出了函数体还能被使用
function loop() {
	for(var i = 0; i < 100; i++)
		console.log(i);
	}
	console.log(i+1);//101

ES6 let, 解决局部作用域冲突问题~

function loop() {
	for(let i = 0; i < 100; i++)
		console.log(i);
	}
	console.log(i+1);// i is undefined

常量

在ES6之前,如何定义常量:大家约定俗成规定把变量名大写的当作常量,且不去修改它。

ES6引入了常量关键字 const

	const PI = 3.14;//不可以修改

方法

定义方法

把函数放进对象里就叫方法,对象里就两个东西:属性和方法。

var Matilda = {
	name : 'Matilda',
	birth : 2002,
	age	: function() {
		var now = new Date().getFullYear();
		//JavaScript跟Java很像,也可以用this去引用自身的属性
		return now - this.birth;
	}
}

//调用属性:
Matilda.属性名;

//调用方法: 方法一定要带()
Matilda.方法名(); 


//方法不写在对象里面:
function getAge() {
	var now = new Date().getFullYear();
		return now - this.birth;
}

var Matilda = {
	name : 'Matilda',
	birth : 2002,
	age	:getAge
}

apply

在 js 中可以控制this指向

function getAge() {
	var now = new Date().getFullYear();
		return now - this.birth;
}

var Matilda = {
	name : 'Matilda',
	birth : 2002,
	age	:getAge
}

//所有的函数都有一个apply方法
getAge.apply(Matilda,[]);//this 指向了Matilda,参数为空。


内部对象

Date

基本使用

var now = new Date();
now.getFullYear();//年
now.getMonth();//月
now.getDate();//日
now.getDay();//星期几
now.getHours();//时
now.getMinutes();//分
now.getSeconds();//秒

//时间戳,世界统一 1970年 1月1日 0:00:00 毫秒数 
now.getTime();//获取时间戳
console.log(new Date(now.getTime()));//时间戳转为时间

JSON

这里只是初步认识一下JSON ,这些都是最原始的。
在JavaScript中一切皆为对象,任何js支持的类型都可以用JSON表示
格式:

  • 对象和Map都用 { }
  • 数组和List都用 [ ]
  • 所有的键值对都使用 key:value

JSON 字符串转 和 JS对象的转化

var person = {
	name : 'Matilda',
	age : 3,
	sex : 'Male'
}
var jPerson = JSON.stringify(person);//转化之后打印出来是一行字符串
var obj = JSON.parse(jPerson);//转化后打印出来是一个对象

JSON 和 JS 对象的区别:

var obj = {name : 'Matilda', age : 3};
var json = '{"name" : "Matilda", "age" : "3"}'

面向对象原型继承

面向对象

JavaScript、Java、c#…
共同点:

  • 类:类是对象的抽象
  • 对象:对象是类的具体表现

ES6 之前:
原型:__proto__ (了解就行了,没必要用)

var person = {
	name : 'people',
	run : function() {
		console.log(this.name + 'can run');
	}
}
var me = {
	name = 'Matilda'
}

//当me对象想要拥有person对象里面的方法时可以用proto
me.__proto__ = person;
//之后才可以调用person里的run方法;
me.run();

//创建一个函数
function student(name) {
this.name = name;
}
//给student 增加一个方法
student.prototype.hello = function() {
	alert('Hello');
}



class 继承

ES6 引入 class 关键字

  1. 定义一个类
class Student{
	constructor(name) {
		this.name = name;
	}

	sayHello() {
		alert('Hello');
	}
}

//实例化class类
var stu1 = new Student('Matilda');
var stu2 = new Student('Mike');
stu1.sayHello();
  1. 继承
class pupil extends Student{
	constructor(name,grade) {
		super(name);
		this.grade = grade; 
	}
	
	selfItr() {
		alert('I am a pupil');
	}
}

这个继承的本质还是原型~

  1. 原型链(JS里叫原型链,Java里叫继承)

操作BOM对象 (重点)

JavaScript的诞生就是为了能够让它在浏览器中运行!

  • BOM 浏览器对象模型

window对象

window (重要)

其中还有很多方法和属性可以获取,可以自己去试一下。

navigator

Navigator,封装了浏览器信息


大多数时候不会使用 navigator 对象,因为会被人为修改

screen

全屏幕属性

location (重要)

location 代表当前页面的URL信息
可以利用它来给页面做重定向
百度的location信息

	reload:ƒ reload() //刷新网页
	assign:ƒ assign() //重定向

document

  • document 代表当前页面,HTML DOM树文档

  • 获取具体的文档树节点:
  • 获取 cookie

    以前学前端只是知道有cookie 和 session 这两个东西可以缓存一些数据,没想到听完狂神讲完cookie劫持之后,我大为震撼,看来网络安全确实重要!
    设置完 cookie: httpOnly 之后会变得安全,具体的以后我再去深究一下。

history

代表浏览器的历史记录

	history.back() //后退
	history.forward() //前进

操作DOM对象 (重要)

获取 DOM 节点

DOM:文档对象模型

核心

浏览器网页就是一个DOM文档树形结构

  • 更新:更新DOM节点
  • 遍历:得到DOM节点
  • 删除:删除一个DOM节点
  • 添加:添加一个DOM新节点

要操作一个DOM节点,就必须要先获得该节点
获取dom节点(原生代码),尽量用jQuery

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>


</head>
<body>

<div id="father">
    <h1>一级标签</h1>
    <p id="p1">This is a p</p>
    <span class="span1">This is a span</span>
</div>


<script>

    //对应css选择器
    let h1 = document.getElementsByTagName('h1');
    let p = document.getElementById('p1');
    let span = document.getElementsByClassName('span1');
    let father = document.getElementById('father');

    let childrens = father.children;//获取父节点下的所有子节点
    // father.firstChild
    // father.lastChild

</script>
</body>
</html>

更新 DOM 节点

<div id="father">

</div>

<script>
    //操作文本
    let father = document.getElementById('father');
    father.innerText = '123';//可以修改节点内的文本内容
    father.innerHTML = '<strong>123</strong>';//可以解析html代码

    //操作css
    father.style.color = 'red';
    father.style.fontSize = '100px';
    father.style.padding = '2em';
</script>

删除 DOM 节点

步骤:先获取父节点,再通过父节点删除子节点

//当只知道子节点的时候可以这样获取父节点
let father = p1.parentElement;
father.removeChild(p1);

//也可以通过下标来删除
father.removeChild(father.children[0]);
//注:每删除一个子节点,后面的节点下标挥往前移,下标是动态变化的

插入节点

如果获得了一个 DOM 节点之后,若该节点是空的,则可以用innerHTML 来添加一个元素,但是如果该节点原先有元素,innerHTML会覆盖所有元素。
在更新 DOM 节点中有举例。

插入(追加已有)节点:

<p id = 'js'>Javascript</p>
<div id = 'list'>
	<p id = 'se'>Java SE</p>
	<p id = 'ee'>Java EE</p>
	<p id = 'me'>Java ME</p>
</div>
<script>
    let js = document.getElementById('js');
    let list = document.getElementById('list');
    list.appendChild(js);
</script>

追加后效果:

创建新标签

  • 方法一:
let p = document.createElement('p');//创建一个p标签
p.id = 'p1';//给p标签加一些属性
p.innerText = 'Hello';
  • 方法二:
let p = document.createElement('p');
p.setAttribute('id','p1');//键值对的形式

操作表单(验证)

目的:提交信息

  • 文本框
  • 下拉框
  • 单/多选框
  • 隐藏域
  • 密码框

操作表单 form

  1. 获取提交信息
<input type="text" id="userName">
<p>
    <span>性别:</span>
    <input type="radio" name="sex" value="man" id="boy"><input type="radio" name="sex" value="woman" id="girl"></p>


<script>

    let inputText = document.getElementById('userName');
    // inputText.value;//获取输入框的值,
    inputText.value = '123';//修改输入框的值

    let boy = document.getElementById('boy');
    let girl = document.getElementById('girl');
    //boy.checked; 判断该选项是否被选中
    //若要获取单选、多选、select框的值时,需要添加if判断哪些框被选中
    
</script>
  1. 提交表单

submit

<form action="index.html" method="post" target="_blank">
    //方法一
    <input type="submit">
    //方法二
    <button type="submit">提交2</button>
</form>

点击事件 onclick

<form action="index.html" method="post" target="_blank">
	<!-- 给提交按钮绑定onclick事件 -->
    <input type="submit" onclick="warning()">
</form>

<script>
//编写onclick事件里的函数
    function warning (){
        alert('This is a warning');
    }
</script>

md5加密

  • 未加密前
<form action="" method="post">
    <p>
        <span>用户名:</span>
        <input type="text" id="userName">
    </p>
    <p>
        <span>密码:</span>
        <input type="password" id="pwd">
    </p>
    <!-- getInfo() 是写出来演示获取自己输入的密码的 -->
    <input type="submit" onclick="getInfo()">
</form>

<script>
    function getInfo (){
        let userName = document.getElementById('userName');
        let pwd = document.getElementById('pwd');
        console.log(userName.value);
        console.log(pwd.value);

    }
</script>

未加密的密码可以直接被抓包获取,不安全!

  • 第一种方法加密后
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    //引入md5 工具类
    <script src="https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js"></script>

</head>
<body>

<form action="#" method="post">
    <p>
        <span>用户名:</span>
        <input type="text" id="userName" name="user">
    </p>
    <p>
        <span>密码:</span>
        <input type="password" id="pwd" name="pwd">
    </p>
    <input type="submit" onclick="getInfo()">
</form>

<script>
    function getInfo (){
        let userName = document.getElementById('userName');
        let pwd = document.getElementById('pwd');

        //md5加密
        pwd.value = md5(pwd.value);

        console.log(userName.value);
        console.log(pwd.value);
    }
</script>
</body>
</html>


第一种方法加密有个缺点,在点击提交按钮之后密码框里面的密码长度会变长闪一下,给用户的体验不是很好。

  • 第二种方法加密
    跟第一种差不多,只不过是使用了一个隐藏的输入框,在网页审查元素的时候看见的加密后的位串是属于隐藏输入框的密码值。
<form action="#" method="post">
    <p>
        <span>用户名:</span>
        <input type="text" id="userName" name="user">
    </p>
    <p>
        <span>密码:</span>
        <input type="password" id="pwd">
        <!-- 利用一个隐藏的输入框来代替原密码框显示加密后的位串 -->
        <input type="password" hidden id="password" name="password">
    </p>
    <input type="submit" onclick="getInfo()">
</form>

<script>
    function getInfo (){
        let userName = document.getElementById('userName');
        let pwd = document.getElementById('pwd');
        
        //获取隐藏的输入框
        let password = document.getElementById('password');
        //给它赋值
        password.value = md5(pwd.value);
    }
</script>

jQuery

jQuery库里,有大量的JavaScript函数

获取jQuery

  • CDN在线引入
  • 下载到本地项目中引入
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <!-- CDN 在线引入 -->
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>


</head>
<body>

<a href="" id="surprise">Click Me !</a>

<script>
    //使用jQuery库中的函数方法:$('选择器').函数名();
    $('#surprise').click(function () {
        alert(111);
    })
</script>

</body>
</html>

选择器

在这里可以查到jQuery支持的所有选择器

jQuery API 中文文档:https://jquery.cuishifeng.cn/

事件

  • 鼠标
  • 键盘
  • 其他事件都可以在我上面分享的在线文档里看到

鼠标事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <!-- CDN 在线引入 -->
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>

    <style>
        #mouseMove {
            width: 500px;
            height: 500px;
            border: 1px solid red;
        }
    </style>

</head>
<body>

mouse:<span id="coordinate"></span>
<div id="mouseMove">
    在这里移动试试
</div>

<script>
    //等待页面元素加载完了之后再执行事件 ready()
    $(function () {
        //参数名可自拟
        $('#mouseMove').mousemove(function (e) {
            //获取鼠标坐标
            $('#coordinate').text('x: ' + e.pageX + 'y: ' + e.pageY)
        })
    });

</script>

</body>
</html>

操作DOM

  • 节点文本操作
<ul id="ul-test">
    <li name="java">Java</li>
    <li name="python">python</li>
    <li>JavaScript</li>
</ul>


<script>
	(这里面都是选择器)
    $('#ul-test li[name=java]').text();//获得值
    $('#ul-test li[name=java]').text('123');//设置值
    $('#ul-test').html();//获得值
    $('#ul-test').html('<span> I Love China! </span>');//修改值,直接把父元素里的子元素全部替换掉
</script>
  • css 操作
	$('#ul-test li[name=java]').css("color","red");
	$('#ul-test li[name=java]').show();//显示元素
    $('#ul-test li[name=java]').hide();//隐藏元素

一些资源网站

本文章用到的md5、jQuery的导入资源网站

CDN:https://www.jq22.com/cdn/
			https://www.jq22.com/cdn/

以上都是我跟着狂神学Java 前端基础 时的一些代码和感悟,纯属当作笔记来分享,如果大家发现了我笔记中的错误,可以多多指正,我会认真修改,虚心求教的!