JavaScript—基础
之前为了找bug浅浅地接触一下的JS
JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言。被广泛的应用于Web开发。
写JavaScript的位置:
页面script标签
<script>js代码</script>
(推荐)<script language="javascript">js代码</script>
js脚本没有固定位置
外部脚本引入(推荐)
创建:xxx.js
引入:<script src="路径/xxx.js"></script>
标签属性中(不常用,不推荐)
<div onclick="js代码"></div>
一、变量声明
1 | var x = 10; //不做声明的时候默认var,重复定义会覆盖,存在变量覆盖变量污染问题。(不推荐) |
- 可一次定义一个或多个变量
- 变量定义后,若没有赋值,那么变量会被赋予一个初始值——undefined(未定义)
变量的命名规范:
- 可以使用
数字、字母、下划线(_)、美元符号($)
的组合,且不能以数字
开头 - 严格区分大小写(比如 A 和 a 不是同一个变量)
- 不能使用保留字或关键字
二、输出
2.1 console.log();
可以在浏览器的控制台输出信息,便于调试程序
2.2 日志
在浏览器控制台中打印日志。一般用来做代码调试。
1 | console.log('普通日志'); |
2.3 弹窗
根据浏览器不同弹窗框样式不一样且无法修改样式
alert()
普通弹窗。一般用来做代码调试confirm()
确认弹窗,有确认和取消两个选择。配合赋值可以得到用户的选择prompt()
输入弹窗,有输入框可以输入文字。配合赋值可以得到用户输入的内容
三、数据类型
- 检测和转换类型函数
typeof()
:检测数据的类型Number()
、String()
、Boolean()
:转换数据类型parseInt()
parseFloat()
:取整数或者浮点数。
3.1 Number类型
JavaScript不区分整数、浮点数等,统一都叫Number。typeof 100
得到 "number"
。
浮点数精度问题
JS数值的运行会先将数值转为二进制,这种标准下小数可能会表示不全,导致最终的结果出现误差。
为了得到相对准确的结果,一般会将小数转为整数之后再进行运行,最后除以倍数。举个🌰:
1
2console.log( 0.1111+0.2222 ); //0.33330000000000004
console.log( (0.1111*10000+0.2222*10000)/10000 ); //0.3333JavaScript 中的 Number 类型只能表示[ -(253 - 1) , (253 -1)] 之间的数值。
Number 类型中还有一些比较特殊的:
- Infinity:表示正无穷大的数值
- -Infinity:表示负无穷大的数值
- NaN:(Not a Number)即非数值,用来表示无效或未定义的数学运算结构,如 0 除以 0
3.2 String类型
三种引号都能表示str
1
"文字" 'str' `abcd`
转义字符
1
2console.log( "I'm a cool guy." ); //一种引号里面可以使用其他两种引号
console.log( "I said,\"Hello World.\"" ); //引号内部使用相同的引号,则需要使用 \ 转义符号字符串拼接
进行
+
运算时,两边任意一边的数据是字符串的话,则是拼接的功能1
2console.log("123" + "4"); //"1234"
console.log("123" + 4); //"1234"
3.3 Boolean类型
布尔类只有两个值:真true
假false
。用于判断。
注意:在python里首字母要用大写:True False
3.4 Undefined类型
未定义类型的值为undefined
在变量没有被赋值时,默认值也为undefined
。
3.5 Null类型
null
和undefined
意义很接近,都表示“没有”。null
可以理解为一个“空”对象,但并不占据内存空间。通常在一个变量即将在后续的逻辑中被赋予一个对象值,但刚开始定义的时候不能确定到底是哪个对象值时,赋予它初始值null
。
注意:typeof null
得到"object"
。
3.6 Object类型
JS中object类型包含数组、普通对象、DOM节点、内置对象、函数等等
3.6.1 数组
取值用
[数字序号]
下标,从0开始计数,数组中可以存放数组。取值超出最大值时,得到undefined
1
2
3
4
5let arr = [10,["Blind","Arbiter",[true,false]]];
console.log(arr[0]); //10
console.log(arr[1][0]); //"Blind"
console.log(arr[2][1]); //false
console.log(arr[4]); //undefined数组拥有
length
属性,可以得到数组存放的数据的个数。1
2
3
4let a = [1,2];
let b = [3,4,,5,];
console.log(a.length); //2
console.log(b.length); //4 最后面没有值的话,不算个数,中间的,,之间即使没有数据也算个数修改值或者新增删除值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21//指定下标式修改、新增数据
let arr1 = [1,2];
arr1[0] = 111;
arr1[2] = 3;
console.log(arr1); // [111,2,3]
//通过设定数组长度删除值
let arr2 = [7,8,9];
arr2.length = 2;
console.log(arr2); //[7,8]
//增
arr.unshift('001'); //加在最前
arr.pull('100'); //加在末尾
arr.splice(指定下标,往后删除数据个数,"增加的数据1","数据2"...); //指定位置加入
//删
arr.shift(); //头
arr.pop(); //尾
arr.splice(指定下标,往后删除数据个数); //指定
//清空数组
arr = []
arr = null
3.6.2 普通对象
对象以键值对形式存储数据。键=对象属性,值=具体数据。
属性的命名规则比变量更宽松。属性名允许是数字,不规范的属性名字可以加
" "
变成一个正确的属性名。取值时使用
.
操作符。1
2
3
4
5
6
7
8
9
10let a = {
name : "BlindArbiter",
"age" : 10000, //属性可以加 "" 类似字符串的写法,也可以不加
"a b c" : true, //不规则的属性名,必须加 "",不加会报错
20 : null //自然数数字可以充当属性名,不必加 ""
friend : ["张三","李四"]
};
console.log( a.age ); //10000
console.log( a.friends[0] ); //"张三"
console.log( a.hobby ); //undefined当属性是一个数据时,使用
[]
来取值1
2
3let a = "age";
console.log( xz[a] ); //18
console.log( xz.a ); //undefined对象可以取值,也可以重新赋值,也可以新增属性
1
2
3
4
5let obj = {a : 10};
obj.a = 20;
obj.b = 30;
console.log(obj); //{a:20,b:30}
3.6.3 函数
函数是一个极为特殊的对象。
定义函数并执行
1
2
3
4
5
6
7
8
9
10
11
12//定义函数
let a = function(){
//js代码
};
function b(){
//js代码
return 返回值
}
//执行函数
a();
b();//函数不调用则不执行匿名函数
1
2
3
4
5
6
7
8//定义匿名函数
function(){}
//定义箭头函数(也是匿名函数的一种)
() =>{
//js代码
}
//执行
(()=>{})()object类型的数据,
typeof
会得到object
,但是函数在typeof
时得到function
四、运算符
4.1 算术运算符
+
不同情景的不同作用:1
2
3let a = 1 + 2; //结果:3 算术运算
let b = 1 + "2"; //结果:"12" 拼接运算,+号两边任一边有字符串,+号就是拼接的作用
let c = +"1"; //结果:1 +号前面没有数据,类似Number()功能,将数据转换为数字,转不了得到NaN-
不同情景的不同作用:1
2
3
4let a = 2 - 1; //结果1 算术运算
let b = "2" - 1; //结果1 当成数字来运算
let c = -1; //结果-1 负号
let d = -"1"; //结果-1 同+号前面都没有时情况一样,只不过最终结果带上 负号 -++ --
前置后置自增自减 (同C)1
2
3
4let x = 3;
console.log(x++); //3 //此时x=3+1=4 //可以理解为先赋值再运算
console.log(++x); //5 //可以理解为先运算再赋值
// ++/-- 就是 +1/-1
4.2 隐式类型转换
不同类型的数据进行运算时会进行隐式类型转换:
1 | //num和str进行+运算时,会转换成str再运算 |
4.3 赋值运算符
1 | = += -= *= /= %= |
x += 10;
相当于 x = x+10;
,其他同理,不多说。
注意:,
可表示在一条语句里面执行多个事情
1 | let x = (1,2,3,4,5); //x值最终为5 |
4.4 比较运算符
1 | == === != !=== > < >= <= |
- 运算后得到布尔值。
==
判断值等不等,===
判断值和类型等不等。 - 字符串比较大小时,是按位比较各自的编码。
"5">"20"
得到true
。 - 对象在进行相等判断时,比较的是内存地址。
4.5 逻辑运算符
1 | && || ! |
与或非,!
的结果始终是一个布尔值。
4.6 三目运算符
1 | 条件表达式 ? 表达式1 : 表达式2 ; |
条件成立执行表达式1,不成立则2
五、判断、循环
js里基本判断语句和基本循环语句的格式同C,直接过,这里不多讲了
5.1 判断 选择
if else if else
1
2
3
4
5
6
7
8
9
10
11
12if( 条件1 )
{
//条件1为真时执行的代码
}
else if( 条件2 )
{
//条件1假 条件2真时执行的代码
}
else
{
//条件1、2都不满足时执行的代码
}switch
1
2
3
4
5
6
7
8
9
10
11
12
13
14switch(a){
case "1":
//code1
break;
case "2":
//code2
break;
case "3":
//code3
break;
default:
//code4
break;
}
5.2 循环
js的for循环,我愿称之为C+Python的结合版
1
2
3for(语句1; 语句2; 语句3){
//循环code
}while
1
2
3
4
5
6
7while( 条件 ){
//循环code
}
do{
//循环code
}while( 条件 )
还有,终止整个循环的break、终止单次循环的continue
5.3 数组循环
for遍历对象
1
2
3
4a={1}
for(const key in a){
console.log(key, a[key]); //key value //a[key]表示可变的值
}forEach()
方法1
2
3
4
5
6
7const arr1 = [33,44,55];
let arr2=[11,22];
arr1.forEach(function(value){
arr2.push(value)})
arr2.forEach((内容,下标)=>{
console.log(内容,下标)
}) //根据本人多次尝试发现,forEach只传一个非纯数字参数的时候只输出内容,两个任意非等非纯数字参数时则输出内容和下标map()
映射:把一个原数组映射成对应的新数组1
2
3
4let arr1 = [1,2,3,4]
let arr2 = arr1.map(function(value){
return value*value
})
六、字符串、数组常用方法
6.1 字符串方法
length
字符串长度,只能读取不可修改charAt()
获取某一个字符串项,可以代替[ ]下标获取substring()
截取字符串1
2
3
4
5
6
7let str = "HelloWorld"
console.log(str.length)
//获取字符串中的某个数据
console.log(str[1]) //e
console.log(str.charAt(1))//e
//参数1为起始位置(包含),参数2结束位置(不包含),参数2不写默认截取所有
console.log(str.substring(1,4)) //ellcharCodeAt()
返回指定位置的字符串unicode编码String.fromCharCode()
通过unicode编码返回对应的字符1
2
3let str = "JavaScript"
console.log(str.charCodeAt(2)) //118
console.log(String.fromCharCode(11097)) //⭙字符串.toUpperCase()
大写转小写(不接受参数)字符串.toLowerCase()
小写转大写(不接受参数)split()
切割字符串变数组(同python)1
2let str = "hello world"
console.log(str.split("")) //['hello','world']
6.2 数组方法
length
数组长度,不同于字符串的是数组长度可读可修改1
2
3
4
5
6
7let arr = [1,2,3,4]
console.log(arr.length) //4
//数组长度可改变,数组内容也发生改变
arr.length = 2
console.log(arr) //[1,2]
arr.length = 6 //数组长度增加 对应空数组项是undefined
console.log(arr[5]) //undefined //获取数组的某一数据push()
依次往数组后面添加数组项pop()
删除数组最后一项1
2
3
4
5let arr = [1,2,3]
let arr1 = arr.push(4,5)
console.log(arr) //[1,2,3,4,5]
let arr1 = arr.pop()
console.log(arr) //[1,2,3,4]shift()
移除数组第一项,同时数组长度-1unshift()
在数组前添加一项数据1
2
3
4
5let arr = [1,2,3]
let arr1 = arr.shift()
console.log(arr) //[2,3]
let arr1 = arr.unshift(0)
console.log(arr) // [0,2,3]splice(index,num,info)
- index 从第几个项开始
- num 往后删除几个数组项
- info 从删除位置开始添加数组项
1
2
3
4
5
6
7
8
9
10
11
12
13let arr = [1,2,3,4,5]
arr.splice(2,3,"a","b")
console.log(arr) //[1,2,"a","b"]
//1.=push()
let arr = [1,2,3,4]
arr.splice(arr.length,0,5) //[1,2,3,4,5]
//2.=pop()
arr.splice(arr.length-1,1) //[1,2,3,4]
//3.=shift()
arr.splice(0,1) //[2,3,4]
//4.=unshift()
arr.splice(0,0,5) //[5, 2, 3, 4]sort()
数组排列 接受一个函数作为参数,函数有两个形参1
2
3
4
5let arr = [22,44,11,33,55]
arr.sort(function(a,b){
return a - b //从小到大排列
return b - a //从大到小排列
})concat()
合并两个数组为一个新的数组1
2
3let arr1 = [1,2]
let arr2 = ["a","b"]
console.log(arr1.concat(arr2)) //[1, 2, 'a', 'b']join()
根据参数规则返回新的字符串,不改变原数组1
2
3let arr = [1,2,3,4]
let arr1 = arr.join("-")
console.log(arr1) //1-2-3-4isArray()
判断接受的对象是否是数组,因为如果直接用typeof检测数组将返回object1
2let arr = [1,2,3]
console.log(Array.isArray(arr)) //true
6.3 字符串和数组两者通用方法
indexOf()
顺序检索lastIndexOf()
倒序检索
1 | //只有一个参数,返回下标 |
七、基础DOM操作
DOM(Document Object Model)文档对象模型。规定了一些用于操作HTML页面的API。
API(Application Programming Interface,应用程序接口)是一些预先定义的,已经拥有某些功能的函数或属性。我们可以直接按照自己的需求来使用。
7.1 获取页面元素
JS中要操作HTML标签,得先获取到对应的标签,我们称之为元素或者节点对象。
通过选择器获取(推荐)
1
2document.querySelector("#main .nav");
document.querySelectorAll("#banner li"); //获取多个 //或者可以理解为选中同一种标签通过ID获取(推荐)
1
document.getElementById("main")
通过class名获取
1
document.getElementsByClassName("left")
通过标签名获取
1
document.getElementsByTagName("p")
特殊标签的获取
- 获取html标签
document.documentElement
- 获取html标签
获取head标签
document.head
- 获取body标签
document.body
- 获取body标签
获取title标签
document.title
7.2 创建、添加、删除节点
创建节点
1
2
3createElement() //创建一个元素节点
createTextNode() //创建一个文本节点
createDocumentFragment() //创建一个文档碎片,先将多个节点整合到这里面再统一添加添加节点
1
2appendChild() //在元素最后添加一个子节点
insertBefore(a,b) //在元素某个子节点之前添加新子节点,参数a为新节点,参数b为已存在的子节点替换节点
1
replaceChild(a,b) //用新节点替换某个子节点,参数a为新节点,参数b为已存在的某个子节点
删除节点
1
removeChild() //删除元素的某个子节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<div id="test">
</div>
<script>
//获取
let test = document.querySelector('#test');
console.log(test);
//创建
let h3 = document.createElement("h3");
let a = document.createElement("a");
//插入内容
h3.innerText='这是什么链接?点一下';
a.innerText = '传送门';
a.href = 'https://github.com/BlindArbiter';
console.log(a);
//添加
test.appendChild(h3);
test.appendChild(a);
//删除
//test.removeChild(h3)
</script>
7.3 监听事件
事件种类 鼠标事件 onclick左键单击
、ondblclick左键双击
、oncontextmenu右键单击
、
onmouseover onmouseenter鼠标移入
、onmouseout onmouseleave鼠标移出、
、onmousedown鼠标按下
、onmousmove鼠标移动
、onmouseup鼠标抬起
键盘事件 onkeydown onkeypress 键按下
、onkeyup键抬起
系统事件 onload加载完成后
、onerror加载出错后
、onresize窗口调整大小时
、onscroll滚动时
表单事件 onfocus获取焦点后
、onblur失去焦点后
、onchange改变内容后
、onreset重置后
、onselect选择后
、onsubmit提交后
监听事件写法
DOM节点.on事件 = 函数(){ code }
这里的函数称之为事件函数,它不会自执行,而是当事件触发时才执行。
操作HTML内容
DOM节点.innerHTML
获取/修改 元素的HTML内容DOM节点.innerText
获取/修改 元素的文本内容this
在事件函数中,
this
表示触发事件的这个节点对象,可以类比一下C++的this指针。
八、属性操作、样式操作
8.1 操作样式
修改样式
JS想要改变元素的样式,那么就相当于要改变控制元素的css(三种样式 ):
- 外部样式 :前端的JS不能修改一个外部的文件,所以无法直接修改外部样式来改变元素。
- 内部样式:内部样式放置到
style
标签中,而style又在当前页面中,所以能被JS控制。(麻烦,不推荐) - 行内样式:直接写在标签中,并且优先级最高。(最常用)
节点.style.属性
来控制单个的行内样式。节点.style.cssText
来控制节点的所有行内样式。Tip:当单个标签操作的样式比较多时,直接改变class来改变样式会方便很多。
获取样式
.style
只能获取行内样式,要获取元素的最终显示样式使用getComputedStyle(节点)
。
8.2 操作class名字
使用 .className
可以来操作标签的类名,但是需要新加一个类名,或者去掉某个类名时,使用.className
较为麻烦。所以推荐使用新API.classList
来操作类名。
- 添加:
节点.classList.add("类名")
- 移除:
节点.classList.remove("类名")
- 切换(有则删,无则加):
节点.classList.toggle("类名")
- 判断是否有某个类名(得到布尔值):
节点.classList.contain("类名")