IMUT-LF

JS-学习笔记

JavaScript

JS是一门脚本语言,ECMAScript可以理解为JS的一个标准

 

1、快速入门

1.1、引入JavaScript

①内部标签:

写在html文件内部:
<script type="text/javascript">
//......
   /**/
</script>

②外部引入:

写在.js文件中,需要在html文件中引入:(此处script标签必须成对出现)
<script src="js文件位置"></script>

 

1.2、基本语法入门

console.log(...);       //在浏览器的控制台打印变量
document.write(...); //在网页上显示指定内容
例:
<script type="text/javascript">
   //多个打印方式,打印在不同位置
   /* alert("hello,world!");
  document.write("媒体元素");
  console.log("控制台"); */

   // 1.定义变量
   var num = 1;
   //alert(num);

   //2.条件控制
   if(num<10){
       alert(num+"<10");
  } else if(num<20){
       alert("10<"+num+"<20");
  } else{
       alert(num+">20");
  }

</script>

 

1.3、数据类型

变量:var 变量 = ... ;

number:js不区分小数和整数,Number

  • NaN:NaN不是一个数字,与所有的数值都不相等,包括自己

    只能通过isNaN()判断

  • Infinity无限大

  • 尽量避免使用浮点数进行运算,存在精度损失。可以通过与0.0000001比较这样的方式判断两个数是否相等

    如:Math.abs(1/3-(1-2/3))<0.00000001

     

字符串:' ' 或 " "

布尔值:true、false

逻辑运算:&&、||、!

比较运算符:=(赋值)、==(类型不同值相同也为true)、===(绝对等于:类型一样值一样才为true)

null 和 undefined:null--空、undefined--未定义

数组( 中括号:[ ] ):可以存放任意多个任意类型的数值

//保证代码的可读性,尽量使用[]
var arr = [1,2,3,"4",5.0,true,null,NaN];

new Array(1,2,3,"4",5.0,true);

取数组下标:如果越界了,就会报 undefined

对象( 大括号:{ } ):每个属性之间用逗号(,)隔开,最后一个不需要添加

如:
var person={
   name:"liufeng",
   age:22,
   tags:['js','java','web','...']
}
取对象的值:(网页console中)
person.name
> "liufeng"
person.age
> 22
person.tags
> (4) ["js", "java", "web", "..."]

 

1.4、严格检查模式

"use strict":严格检查模式,预防JavaScript的随意性导致产生的一些问题(必须写在JS的第一行)

局部变量建议都使用 let 定义

<script type="text/javascript">
   "use strict";
let i=1;
</script>

 

 

2、数据类型

2.1、字符串

1、正常字符串用 单引号 或 双引号 引起来

2、注意转义字符 \

3、支持多行编写(用 `` 引起来)

4、模板字符串

如:
let name = "liufeng";
let msg = `你好呀,${name}`;

5、多个属性和方法:如:s.length、s.toUpperCase()、s.indexOf(...)、s.substring(.. ,..)

6、字符串的可变性:不可变(不能替换)

 

2.2、数组

Array可以包含任意的数据类型

1、长度:arr.length

注:假如给 arr.length 赋值,数组大小就会发生变化;多出来的元素为 undefined;如果赋值过小,元素就会丢失

2、常用方法:(用数组对象调用)

indexOf(...):获得指定元素第一次出现的下标索引(字符串的"1"和数字1是不同的)

slice(...):截取数组的一部分,返回一个新的数组(类似于字符串的substring)

push(...):向数组中尾部添加元素

pop(...):从数组中尾部弹出元素

unshift(...):向数组中头部添加元素

shift(...):从数组中头部弹出元素

sort():给数组排序

reverse():元素反转

concat(...):拼接元素(该方法并没有修改数组,只是会返回一个新的数组)

join(...):连接符,使用指定的连接符打印拼接数组

3、多维数组:

如:arr = [[1,2],["3","4"],[true,false]];
arr[1][1];
>"4"

 

2.3、对象

若干个键值对

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

JS中的所有键都是字符串,值是任意对象

1、对象赋值:直接 对象名.属性名 = 属性值

2、使用一个不存在的对象属性,不会报错(报 undefined)

3、动态的删减属性:通过 delete 删除对象的属性

如:
delete person.name
true

4、动态的添加属性:直接给新的属性添加值即可

如:
person.name = "zhangsan";(name属性原来不存在)

5、判断属性值是否在某个对象中:’属性名‘ in 对象

如:
'name' in person
> true
'toString' in person
> true

6、判断一个属性是否是某个对象自身拥有的:hasOwnProperty()

如:
person.hasOwnProperty("toString");
> false
person.hasOwnProperty("name");
> true

 

2.4、流程控制

if 判断:if(...){...} else if(...){...} else{...}

while循环:while(...){...}(避免程序死循环)

for循环:for(let i=...){}

for in循环:

var age=[1,2,3,4,5,6,7,8];
for (let num in age) {		//此处num为索引
    console.log("num:"+age[num]);
}

for of循环(ES6):

var age=[1,2,3,4,5,6,7,8];
for (let num of age) {		//此处num为数值
    console.log("num:"+num);
}

forEach循环:

forEach:
var age=[1,2,3,4,5,6,7,8];
age.forEach(function(v){
    console.log(v);
});

 

2.5、Map 和 Set

ES6的新特性

1、Map

var map = new Map([["tom",99],["jack",98],["lily",95]]);
var score = map.get("tom");		//get方法获取指定键的值
console.log(score);
map.set("mike",90);		//set方法可添加键值对或修改键值对
map.delete("tom");		//删除指定键值对

遍历map:

var map = new Map([["tom",99],["jack",98],["lily",95]]);
for(let e of map){
    console.log(e);
}

 

2、Set:无序不重复的集合

var set = new Set([1,1,1,1,3]);	//set可以自动去重
set.add(2);			//添加
set.delete(1);		//删除
console.log(set.has(3));		//是否包含某个元素

遍历Set

var set = new Set([1,1,1,1,3]);	//set可以自动去重
for(let s of set){
    console.log(s);
}

 

2.6、iterator

ES6新特性

 

3、函数

3.1、定义函数

定义方式一

如:绝对值函数
function abs(x){
    if(x >= 0){
        return x;
    } else {
        return -x;
    }
}

执行到 return 代表函数结束,返回结果

如果没有执行 return (如没有传入参数),函数执行完也会返回结果,结果就是 NaN

 

定义方式二

var abs = function(x){
    ...
}

相当于匿名函数,但是可以把结果赋值给abs,通过abs就可以调用函数

(方式一等价于方式二)

 

3.2、函数调用

函数名(参数)

参数问题:JS可以传任意个参数,也可以不传递参数

假设没有输入参数,如何规避:

在函数中加上以下句段:
if(typeof x !== 'number'){
    throw "Not a number";
}

arguments

arguments代表传递进来的所有参数,是一个数组

此处代码皆在函数中:
for(let i=0; i<arguments.length; i++){
    console.log(arguments[i]);
}

问题:arguments包含所有的参数(包括第一个),我们有时候想使用多余的参数进行附加操作,需要排除已有的参数

 

rest

ES6引入的新特性,获取除了已经定义的参数之外的所有参数

以前:
if(arguments.length > 2){
   for(let i=2; i<arguments.length; i++){
       ...
   }
}
现在:
function test(a,b,...rest){
    console.log("a=>"+a);
    console.log("b=>"+b);
    console.log(rest);
}

rest 参数只能写在参数最后面,必须用 ...rest 表示

 

3.3、变量的作用域

在JS中,var 定义的变量实际是有作用域的

假设在函数体中声明,则在函数体外不可以使用(若要实现,需要闭包

内部函数可以访问外部函数的变量

若内部函数和外部函数有同名变量,互不影响

提升变量的作用域

JS执行引擎自动提升变量的声明,但是不会提升变量的赋值

建议JS中所有的变量定义都放在函数的头部,便于维护

全局变量

直接在函数外部定义变量

 

全局对象 window

默认所有的全局变量都会绑定在 window 对象下(如 alert() 这个函数本身也是一个 window的变量)

JS 实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,就会报错 RefrenceError

 

规范

由于我们所有的全局变量都会绑定到我们的 window 上,如果不同的 js 文件使用了相同的全局变量,就会产生冲突。

减少冲突的方法:

//唯一全局变量
var Liu = {};

//定义全局变量
Liu.name = "imut_liu";
Liu.add = function(a,b){
return a+b;
}

把自己的代码全部放入自己定义的唯一空间中,降低全局命名冲突的问题

 

局部作用域 let

ES6 let 关键字,解决局部作用域冲突问题

建议使用 let 关键字定义局部变量(如for循环中的 i 变量)

 

常量 const

ES6之前:用全部字母大写命名常量

在ES6引入了常量关键字:const

 

3.4、方法

定义方法

方法就是把函数放在对象内部,对象只有属性和方法两种内容

var Liu = {
    name:"liufeng",
    birth:1999,
    //方法
    age:function(){
        //今年 - 出生的年
        let year = new Date().getFullYear();
        return year - this.birth;
    }
};

//获取对象属性
Liu.name
//获取对象方法,要带括号
Liu.age()

this 代表当前调用该方法的对象(window调用函数,对象调用方法)

 

apply

在JS中可以控制 this 的指向

function getAge(){
    //今年 - 出生的年
    let year = new Date().getFullYear();
    return year - this.birth;
}

var Liu = {
name:"liufeng",
birth:1999,
//方法
age:getAge
};

getAge.apply(Liu,[]); //this指向了Liu,参数为空

 

4、内部对象

标准对象

typeof 123
"number"
typeof "1999-03-24"
"string"
typeof true
"boolean"
typeof NaN
"number"
typeof []
"object"
typeof {}
"object"
typeof Math.fround
"function"
typeof undefined
"undefined"

 

4.1、Date

基本使用

var date = new Date();	//Fri Aug 14 2020 16:18:01 GMT+0800 (中国标准时间)
date.getFullYear();		//年
date.getMonth();		//月	0-11	代表月
date.getDate();			//日
date.getDay();			//周几
date.getHours();		//时
date.getMinutes();		//分
date.getSeconds();		//秒

date.getTime(); //时间戳 全世界统一,从1970-1-1 00:00:00开始到现在的毫秒数

console.log(new Date(1597393505254)); //把时间戳转为时间

转换

date.toLocaleString();		//注:调用的是一个方法
"2020/8/14 下午4:27:23"
date.toGMTString();
"Fri, 14 Aug 2020 08:27:23 GMT"

 

4.2、JSON

json是什么

早期,所有数据传输习惯使用 XML 文件

  • JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式

  • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言

  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率

 

在JS中一切皆为对象,任何JS支持的类型都可以用JSON来表示

格式:

  • 对象都用 { }

  • 数组都用 [ ]

  • 所有的键值对都使用 key:value

 

JSON字符串和对象的转化

var user = {
    name:"liufeng",
    age:22,
    sex:"男"
};

//对象转化为json字符串 {"name":"liufeng","age":22,"sex":"男"}
var jsonUser = JSON.stringify(user);

//json字符串转化为对象 参数为json字符串
var obj = JSON.parse(jsonUser);

 

JSON 和 JS 对象的区别:

JS:
var obj = {a:'helloa', b:'hellob'};
JSON:
var obj = {"a":"helloa", "b":"hellob"};

 

4.3、Ajax

  • 原生的 js 写法:xhr 异步请求

  • jQuery 封装好的方法:$("#id名").ajax("")

  • axios 请求

 

5、面向对象编程

原型:

var user = {
    name:"liufeng",
    age:22,
    run:function(){
        console.log(this.name+" run... ");
    }
};

var xiaoming = {
name:"xiaoming",
};

//xiaoming 的原型是 user
xiaoming.proto = user;

 

class继承

class关键字在ES6引入

//ES6之后
//定义一个学生类
class Student{
    //构造器
    constructor(name){
        this.name = name;
    }
    //方法
    hello(){
        alert("hello");
    }
}

var xiaoming = new Student("xiaoming");

继承

<script type="text/javascript">
    'use strict';

//ES6之后
//定义一个学生类
class Student{
//构造器
constructor(name){
this.name = name;
}
//方法
hello(){
alert("hello");
}
}

var xiaoming = new Student("xiaoming");

class YoungStu extends Student{

constructor(name,grade) {
    super(name);
    this.grade = grade;
}

myGrade(){
    alert("我是一名"+this.grade+"年级小学生");
}

}

var xiaohong = new YoungStu("xiaohong",1);

</script>

本质还是父类

 

原型链

__ proto __

 

6.操作 BOM 对象(重点)

BOM:浏览器对象模型

 

window(重要)

window 代表 浏览器窗口

window.alert(1);
undefined
window.innerHeight;
722
window.innerWidth;
948
window.outerHeight;
824
window.outerWidth;
1536
//调整浏览器窗口大小后会变化

 

navigator(不建议使用)

navigator 封装了浏览器的信息

navigator.appName;
"Netscape"
navigator.appVersion;
"5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36"
navigator.userAgent;
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36"
navigator.platform;
"Win32"

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

不建议使用这些属性来判断和编写代码

 

screen

screen 代表屏幕

screen.width;
1536(单位应该为px)
screen.height
864

 

location(重要)

location 代表当前页面的URL信息

如在百度页面console中打location
会出现许多信息
如:
...
host: "www.baidu.com"
href: "https://www.baidu.com/"
protocol: "https:"
reload: ƒ reload()		//刷新网页
assign: ƒ assign()		//设置新的地址
...

 

document(重要)

document 代表当前的页面

1.可以通过 document 获取具体的文档树节点

<body>
    <dl id="app">
        <dt>Java</dt>
        <dd>JavaSE</dd>
        <dd>JavaEE</dd>
	</dl>	
    <script type="text/javascript">
        var dl = document.getElementById("app");
    </script>
</body>

2.可以获取 cookie

document.cookie
"BIDUPSID=09EA8765168AB000EDC42294EE713778; PSTM=1587433683; BAIDUID=09EA8765168AB000B44D349DB0879318:FG=1; "

劫持 cookie 原理:某人恶意向某网站注入 js 文件,获取你的 cookie 上传到他的服务器,从而获取你的信息甚至操作你的内容

服务器端可以设置 cookie 为:httpOnly

 

history(不建议使用)

history:代表浏览器的历史记录

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

 

7、操作 DOM 对象(重点)

DOM:文档对象模型

核心

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

  • 添加:添加一个新的 DOM 节点

  • 删除:删除一个 DOM 节点

  • 更新:更新 DOM 节点

  • 遍历 DOM 节点:得到 DOM 节点

要操作一个DOM节点,就必须先获得这个DOM节点

 

获得DOM节点

<body>
    <div id="father">
        <h1>标题一</h1>
        <p class="p1">p1</p>
        <p id="p2">p2</p>
	</div>
&lt;script&gt;
    //对应css选择器
    var father = document.getElementById("father");
    var h1 = document.getElementsByTagName("h1");
    var p1 = document.getElementsByClassName("p1");
    var p2 = document.getElementById("p2");

    var children = father.children;		//获取父节点下的所有子节点
    //father.firstChild;
    //father.lastChild;
&lt;/script&gt;

</body>

 

更新节点

操作文本:

  • 节点.innerText:修改文本的值

  • 节点.innerHTML:可以解析 HTML 文本标签

操作JS:

  • 节点.style.xxx:可以设置各种CSS样式

如:
id1.style.color="blue";		//属性使用字符串表示
id1.style.fontSize="50px";		//驼峰命名
id1.style.fontFamily="华文彩云";

 

删除节点

删除节点的步骤:先获取父节点,再通过父节点删除自己

parentElement

removeChild

如:HTML:
<div id="id1">
    <h1>标题H1</h1>
    <p id="p1">id---p1</p>
    <p class="p2">class---p2</p>
</div>

JS:
var p1 = document.getElementById("p1");
var father = p1.parentElement;
father.removeChild(p1);

删除是一个动态的过程:
father.removeChild(father.children[0]);
father.removeChild(father.children[1]);
father.removeChild(father.children[2]);

注:删除多个节点的时候,children是在时刻变化的,要注意下标变化

 

插入节点

在获得了某个DOM节点后,如果该DOM节点是空的,可以通过innerHTML增加元素;但是如果该DOM节点已经存在元素,再innerHTML会覆盖原来的内容

追加

appendChild(要追加的子节点);

<p id="js">JavaScript</p>
<div id="list">
    <p id="se">JavaSE</p>
    <p id="ee">JavaEE</p>
    <p id="me">JavaMe</p>
</div>

<script>
var js = document.getElementById("js");
var list = document.getElementById("list");
list.appendChild(js); //追加到后面
</script>

 

创建一个新的标签,实现插入

//通过JS创建一个新的节点
var newP = document.createElement("p");	//创建一个p标签
newP.id="newP";
newP.innerText="Hello LiuFeng";
list.appendChild(newP);

//创建一个标签节点(通过这个属性,可以设置任意的值)
var myScript = document.createElement("script");
myScript.setAttribute("type","text/javascript");
list.appendChild(myScript);

//设置标签样式
var body = document.getElementsByTagName("body");
body[0].setAttribute("style","background-color: pink;"); //方法一
//body[0].style.backgroundColor="green"; //方法二

//可以创建一个style标签
var myStyle = document.createElement("style"); //创建一个空的style标签
myStyle.setAttribute("type","text/css");
myStyle.innerHTML="body{background-color: lightpink;}"; //设置标签内容
document.getElementsByTagName("head")[0].appendChild(myStyle); //把style标签添加到head标签下

 

insert

var myH = document.createElement("h1");
myH.innerText="My H1";
var list = document.getElementById("list");
var ee = document.getElementById("ee");
//要包含的节点.insertBefore(newNode, targetNode)
list.insertBefore(myH,ee);

 

8、操作表单(验证)

  • 文本框:text

  • 下拉框:<select> <option></option> </select>

  • 单选框:radio

  • 多选框:checkbox

  • 隐藏框:hidden

  • 密码框:password

  • ......

表单的目的:提交信息

 

获得要提交的信息

节点.value:获取节点当前的值

节点.checked:判断节点是否被选中(如多选框、单选框等等)

<body>
&lt;form method="post"&gt;
    &lt;p&gt;
    &lt;span&gt;用户名:&lt;/span&gt;&lt;input type="text" id="username" /&gt;
    &lt;/p&gt;
	&lt;!-- 单选框的值,就是定义好的value --&gt;
    &lt;p&gt;
        &lt;span&gt;性别:&lt;/span&gt;
        &lt;input type="radio" name="sex" value="man" id="boy" /&gt; 男
        &lt;input type="radio" name="sex" value="woman" id="girl" /&gt; 女
    &lt;/p&gt;
&lt;/form&gt;

&lt;script&gt;
    var username = document.getElementById("username");
    //得到输入框的值:节点.value
    //username.value;
    //修改输入框的值:节点.value = 值;
    //username.value = "LiuFeng"

    var boy_radio = document.getElementById("boy");
    var girl_radio = document.getElementById("girl");	//如girl_radio.value只能获取到当前的值,
    //若要判断是否被选中,可以使用 节点.checked(选中返回true)
&lt;/script&gt;

</body>

 

提交表单:md5加密密码,优化表单

<form action="#" method="post">
    <p>
        <span>用户名:</span><input type="text" id="username" name="username" />
    </p>
	<!-- 单选框的值,就是定义好的value -->
    <p>
        <span>密  码:</span><input type="password" id="pwd" name="pwd" />
    </p>
<!-- 绑定事件 -->
    <p>
        <button type="button" value="提交" onclick="sub()" >提交</button>
    </p>
</form>

<script>
function sub(){
var username = document.getElementById("username");
var pwd = document.getElementById("pwd");
console.log(username.value);
//MD5算法加密
pwd.value = md5(pwd.value);
console.log(pwd.value);
}
</script>

以上方法在提交时,密码框内容会变成加密密码,长度变长,不易操作

优化后:

<!-- 表单绑定提交事件
onsubmit绑定一个提交检测的函数:true、false
将该结果返回给表单,使用onsubmit接收-->
    <form action="https://www.baidu.com/" method="post" onsubmit="return sub()">
        <p>
        	<span>用户名:</span><input type="text" id="username" />
        </p>
		<!-- 单选框的值,就是定义好的value -->
        <p>
        	<span>密  码:</span><input type="password" id="input_pwd" />
        </p>
		//通过隐藏域提交
		<p>
            <input type="hidden" id="md5_pwd" name="password" />
        </p>
    &lt;p&gt;
        &lt;button type="submit" value="提交" &gt;提交&lt;/button&gt;
	&lt;/p&gt;

</form>

<script>
function sub(){
alert(1);
var username = document.getElementById("username");
var input_pwd = document.getElementById("input_pwd");
var md5_pwd = document.getElementById("md5_pwd");

            md5_pwd.value = md5(input_pwd.value);

            return true;
        }

</script>

 

9、jQuery

jQuery库,里面存在大量的 JavaScript 函数

获取 jQuery

公式 :$(选择器).事件();

选择器就是CSS选择器

如:
<!-- 
	公式 :$(选择器).action();
-->
    <a href="" id="test-jquery">点我</a>

<script>

    //选择器就是CSS选择器
    $("#test-jquery").click(function(){
        alert("hello,jQuery");
    });

</script>

 

选择器

<script>
    //原生js,选择器少,不好记
    //标签
    document.getElementsByTagName();
    //id
    document.getElementById();
    //类
    document.getElementsByClassName();
//jQuery	可以使用css中全部选择器
//标签选择器
$("标签").action();
//id选择器
$("#id名").action();
//类选择器
$(".类名").action();

</script>

文档工具站:https://jquery.cuishifeng.cn/

 

事件

鼠标事件、键盘事件、其他事件

当网页元素加载完毕之后,响应事件

 

操作DOM元素

节点文本操作:

例:
$("#url_test li[name=cpp]").text();		//text方法无参,获得值
$("#url_test li[name=cpp]").text("...");	//text方法有参,设置值

$("#url_test li[name=cpp]").html(); //与上面同理,解析html文本

 

css操作:

例:
$("#url_test li[name=cpp]").css({"color":"red","fontSize":"20px"});

 

元素的显示和隐藏:

本质:元素属性 display : none

例:
$("#url_test li[name=cpp]").show();		//显示
$("#url_test li[name=cpp]").hide();		//隐藏

 

其他测试:

$(window).width();
$(window).height();
...

 

ajax

$("#form").ajax();

$.ajax({ url: "test.html", context: document.body, success: function(){
$(this).addClass("done");
}});

 

小技巧

1、巩固JS(看jQuery源码,看游戏源码)

2、巩固HTML、CSS(扒网站,down下来,修改看效果)

 

 

posted @ 2021-01-15 21:43  IMUT_LF  阅读(52)  评论(0)    收藏  举报

IMUT-LF