JavaScript基础
JavaScript
概念
运行在浏览器的客户端脚本语言,不需要编译,直接可以被浏览器解析执行
功能
可以来增强用户和html的交互过程,控制html元素
引入方式
- script标签
- scrip标签加src 引用js文件
- 在元素的事件中直接编写js代码
- 与html结合方式
- 内部JS:定义<script>,标签体内容就是js代码
- 外部JS:定义<script>,通过src属性引入外部js文件
- 注意:
- <script>可以定义在html页面的任何地方。但定义的位置会影响执行顺序
- <script>可以定义多个
ECMAScript基本语法
注释
- 单行注释:**//注释内容**
- 多行注释:**/*注释内容*/**
数据类型
- 原始数据类型(基本数据类型):
- number:数字,整数/小数/NaN(not a number)
- string:字符串
- boolean:true和false
- null:一个对象为空的占位符
- undefined:未定义,如果一个变量没有给初始化值,就会被赋值为这个
- 引用数据类型:对象
变量
变量:一小块存储数据的内存空间
Java语言是强类型语言,而JavaScript是弱类型语言
- 强类型:在开辟变量存储空间时,定义了空间将来存储的数据的数据类型。只能存储固定类型的数据
- 弱类型:在开辟变量存储空间时,不定义了空间将来存储的数据的数据类型。可以存储任意类型的数据
语法:
var 变量名 = 初始化值;
1
2
3
4
5
6function foo() {
for (var i=0; i<100; i++) {
//
}
i += 100; '仍然可以引用变量i'
}let 变量名 = 初始化值;
- 可以申明一个块级作用域的变量
1
2
3
4
5
6function foo() {
for (let i=0; i<100; i++) {
//
}
i += 100; '语法错误'
}const 大写变量名 = 初始化值;
- 声明一个常量
1
2
3const A = 1;
A = 3; '赋值没有效果'
console.log(A); '结果还是1'解构赋值
- 同时对多个变量赋值
- 使用解构赋值对对象属性进行赋值时,如果对应的属性不存在,变量将被赋值为undefined
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33// let [x,y,z] = [1,2,3] 或者 let [,,z] = [1,2,3]
var [x,y,z] = [1,2,3];
console.log(x+y+z); '输出6'
var data = {'name':'小米','modal':'Y999','price':'2999'};
var {name,modal,price} = data;
console.log(name); '输出小米'
var data2 = {'name':'张三','address':{'city':'郑州','street':'999号'}};
var {name,address:{city,street}} = data2;
console.log(city); '输出郑州'
var data3 = {'name':'张三','pId':'1001'};
'pId:id这样写是为了让id获取到pId的值'
var {name,pId:id} = data3;
console.log(id); '输出1001'
var data4 = {'name':'张三','pId':'1001'};
"id='无id' 是设置默认值,如果没有id属性就设置为无id,不会显示undefined"
var {name,id='无id'} = data4;
console.log(id); '输出无id'
"声明变量"
var x, y;
"解构赋值,必须加上()不然会报语法错误"
({x,y} = {'x':100,'y':200});
console.log(x+y); '输出300'
"交换变量"
[x,y] = [y,x];
console.log(x); '输出200'
"获取当前页域名和路径"
var {hostname:domain, pathname:path} = location;
typeof运算符:获取变量类型
- 注:null运算后得到的是object
运算符
- 一元运算符:只有一个运算符的运算符
- ++,–,+-(正负号)
- 注意:如果运算符前有正负号,在JS中,如果运算数不是运算符所要求的类型,那么js引擎会自动的将运算数进行类型转换
- string转number:按照字面值转换,如果字面值不是数字,则转为NaN
- boolean转number:true转为1,false转为0
- 算数运算符
- +,-,*,/,%
- 赋值运算符
- =,+=,-=,……
- 比较运算符
- <,>,>=,<=,==,===(全等于)
- 比较方式:
- 类型相同:直接比较
- 字符串比较会按照字典顺序比较,按位逐一比较,直到得出大小停止
- 类型不同:先进行类型转换再比较
- ===:全等于。在进行比较之前,先判断类型是否一致,不一致直接返回false
- 类型相同:直接比较
- 逻辑运算符
- &&,||,!
- 其他类型转boolean
- number:0或NaN为假,其他为真
- string:除了空字符串为假,其他为真
- null和undefined:都是false
- 对象:所有对象都为true
- 三元运算符
- 表达式?值1:值2
流程控制语句
if…else
switch
- 在Java中,switch语句可以接收的数据类型:byte,int,short,char,枚举(1.5),String(1.7)
- 在JS中,switch语句可以接收任意数据类型
while
do…while
for
for … of
1
2
3
4var array = ['1','2','3'];
for(var a for array){
console.log(a); // 输出 1 2 3
}forEach
- 在Array中
- element:指向当前元素的值
- index:指向当前索引
- array:指向Array对象本身
- 在Set中
- element:指向当前元素的值
- sameElement:指向当前对象本身
- set:指向Set对象本身
- 在Map中
- value:指向当前元素的值
- key:指元素的键
- map:指元素的本身
1
2
3
4
5
6
7
8
9
10
11
12
13var array = ['1','2','3'];
array.forEach(function(element,index,array){})
// 或者这样写
array.forEach(function(element){})
var set = new Set(['1','2','3']);
set.forEach(function(element,sameElement,set){})
// 或者这样写
set.forEach(function(element){})
var map = new Map([[1,'x'],[2,'y']])
// 或者这样写
map.forEach(function(value){})- 在Array中
JS特殊语法
- 语句;结尾,如果一行只有一条语句,可以省略(不推荐)
- 变量的定义是用var关键字,也可以不使用
- 用var:定义的变量是局部变量
- 不用var:定义的变量是全局变量(不建议)
1 |
|
- 严格模式
使代码显示地 脱离马虎模式/稀松模式/懒散模式(sloppy)模式
- 通过抛出错误来消除了一些原有静默错误。
- 修复了一些导致JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快。
- 禁用了在ECMAScript的未来版本中可能会定义的一些语法。
使用
- 在JavaScript文件的开头加上’use strict’;
- 在某个函数中**加上’use strict’;**开启严格模式
1
2
3"对当前整个javascript开启严格模式"
'use strict';
var a = 'a';1
2
3
4function a(){
"对当前方法开启严格模式"
'use strict';
}
ECMAScript基本对象
Function函数(方法)对象
创建:
1
2
3
4
5
6
7
8
9
10
11
12"var 方法名 = new Function(形式参数列表,方法体)(不推荐)"
var fun1 = new Function("a","b","alert(a);");
"function 方法名称(形式参数列表){方法体}"
function fun2(a,b){
alert(a+b);
}
"var 方法名 = function(形式参数列表){方法体}"
var fun3 = function(a,b){
alert(a+b);
};属性:
- length:代表形参的个数
特点:
方法定义时,形式参数类型不用写,返回值类型也不写
方法是一个对象,如果定义名称相同的方法,会被覆盖
在JS中,方法的调用只和方法的名称有关,和参数列表无关
在方法声明中有一个隐藏的内置对象(数组)arguments,封装所有的实际参数
在ES6中新加入rest参数用于封装,rest参数只能写在最后,用…标识
1
2
3
4
5function myfun(a,...rest){
console.log(a); '输出'
console.log(rest); '输出[2,3,4]'
}
myfun(1,2,3,4,);
方法:
- this关键字
1
2
3
4
5
6
7var data = {
name:'张三',
age:function(){
console.log(this.name); '输出张三'
},
}- apply使用:接收两个参数,第一个参数就是需要绑定的this变量,第二个参数是Array,表示函数本身的参数
1
2
3
4
5
6
7
8
9
10
11
12
13function getAge() {
var y = new Date().getFullYear();
return y - this.birth;
}
var data = {
name: '小明',
birth: 1990,
age: getAge
};
xiaoming.age(); '输出25'
getAge.apply(data, []); '输出25, this指向xiaoming, 参数为空'- call使用:apply把参数打包成Array再传入,call把参数按顺序传入
1
2
3"判断最大值"
Math.max.apply(null, [3, 5, 4]); '输出5'
Math.max.call(null, 3, 5, 4); '输出5'- 装饰器概念
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17"统计页面总共使用了多少次parseFloat"
var count = 0;
var oldParseFloat = parseFloat;
window.parseFloat = function(){
count += 1;
"调用原函数"
return oldParseFloat.apply(null,arguments);
}
var jj = 1;
var jj2 = 2;
var jj3 = 3;
parseFloat(jj);
parseFloat(jj2);
parseFloat(jj3);
console.log(count); '输出3'调用:方法名称(实际参数列表);
Array数组对象
- var 方法名 = new Array(元素列表);
- var 方法名 = new Array(默认长度);
- var 方法名 = [元素列表]
1
2
3
4
5
6
7
8// 第一种
var arr1 = new Array(1,2,3);
// 第二种
var arr2 = new Array(5);
// 第三种
var arr3 = [1,2,3,4];
filter方法:Array的filter()方法把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素
- element:指的是数组中的单个元素
- index:指的是数组中的索引
- self:指的是数组本身
1 |
|
- sort方法:对Array进行排序,会把传入的数字转为字符串进行排序,默认排序规则是根据ASCII码,所以对数字排序会出现异常,不过sort也是一个高阶函数,可以自定义排序规则
1 |
|
- every方法:判断数组的所有元素是否满足测试条件
1 |
|
- find方法:查找符合条件的第一个元素,如果找到了,返回这个元素,没找到返回undefined
1 |
|
- findIndex方法:查找符合条件的第一个元素,找到返回索引,找不到返回-1
1 |
|
- forEach方法:和map()类似,每个元素依次作用于传入的函数,但不会返回新的数组
- element:指的是数组中的单个元素
- index:指的是数组中的索引
- self:指的是数组本身
1 |
|
- 属性:
- length:数组的长度
- 方法:
- **join(参数)**:将数组中的元素按照指定的分隔符拼接字符串
- **push(参数)**:在尾部添加一个元素
- **sort()**:排序
- **pop()**:删除尾部元素
- **shift()**:删除头部元素
- **unshift()**:在头部添加一个元素
- 特点:
- JS中,数组元素的类型是可变的
- JS中,数组的长度是可变的
Date
- 创建:
- var 方法名 = new Date();
- 创建指定日期:var 方法名 = new Data(2019,12,12,09.09,09,09)
- 注意:JavaScript日期使用是0-11,0表示1月,11表示12月
- 方法:
- **toLocaleString()**:返回为本地时间字符串格式
- **getMonth()**:返回月(0~11)
- **getDate()**:返回日(1~31)
- **gerDay()**:返回星期(0~6)
- **getHours()**:返回小时(0~23)
- **getMinutes()**:返回分钟(0~59)
- **getSeconds()**:返回秒数(0~59)
- **getFullYear()**:返回年。4位数年份
- **getTime()**:返回1970年1月1日至今的毫秒数
Math
- 创建:Math对象不用创建,直接使用
- 方法:
- **random():[0,1)**之间的随机数
- **ceil(值)**:向上取整
- **floor(值)**:向下取整
- **round(值)**:四舍五入
- 属性:PI和其他。。
RegExp(正则)
- 使用:正则表达式教程
- 创建:
- var 名字 = new RegExp(“正则表达式”);
- var 名字 = /正则表达式/;
- 方法:
- test(参数):验证指定的字符串是否符合正则的规范
Global
- 特点:全局对象,Global封装的方法不需要对象就可以直接调用
- 方法:
- encodeURI():URL编码
- decodeURI():URL解码
- encodeURIComponent():URL编码,编码的字符更多一些
- decodeURIComponent():URL解码
- **isNaN()**:判断是否是NaN
- NaN和什么判断都是false,包括自己
- **eval()**:将JavaScript字符串转为脚本代码执行
- **parseInt()**:字符串转换为整数
- **parseFloat()**:字符串转浮点数
- **toString()**:返回字符串
其他
- Boolean
- Number
**toString(数字)**:把数字转换为字符串
1
2
3
4
5'直接使用'
123.toString() '报语法错误'
'使用语法'
123..toString(); '两个点'
(123).toString();**valueOf()**:返回一个Number对象的基本数字值。
- String
- 方法
- **indexOf(字符)**:查找指定字符
- **subString(开始位置,结束位置)**:截取字符串
- **substr(开始位置,截取个数)**:截取字符串,
- **split(指定分割字符)**:分割
- **toUppercase()**:转大写
- **replace(正则,字符串)**:替换与正则表达式匹配的子串
- **lastIndexOf(字符串)**:从后向前搜索字符串
- 方法
- Map
- 创建:
- var map = new Map()
- var map = [‘Michael’, ‘Bob’, ‘Tracy’]
- 注意:如果一个键已经存在,再存一次就会覆盖前面的值
- 方法
- set(键,值):存储键值对
- has(键):判断是否存在该键,返回true和false
- get(键):通过键获取值
- delete(键):删除该键
- 创建:
- Set
- 创建:
- var set = new Set()
- var s2 = new Set([1, 2, 3])
- 方法:
- **add(值)**:添加
- **delete(值)**:删除
- 创建:
扩展
高阶函数
基础:指的是一个函数,可以接收一个函数参数
1
2
3
4
5
6
7
8
9
10function f(x){
return x*10;
}
function test(x,f){
console.log(f(x)); '输出20'
}
'不需要传入(),只需要传入函数名字就可以'
test(2,f);函数作为返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function test(arr){
var t = function(){
return arr.reduce(function(x,y){
return x+y;
});
}
return t;
}
var f1 = test([1,2,3]);
var f2 = test([1,2,3]);
console.log(f1); '输出的是函数体'
console.log(f1()); '输出6'
'多个函数体的调用互不影响'
console.log(f1 === f2); '输出fasle'