一、简介
1、脚本语言:JS 引擎执行代码时逐行解释
每一句源码(转换为机器语言),然后由计算机去执行,所以 JavaScript 语言归为脚本语言,会逐行解释执行
2、组成:DOM-文档对象模型、BOM-浏览器对象模型、ECMAScript
3、多行注释快捷键:shift+alt+/,单行注释:ctrl+/
二、输入输出语句
方法 | 说明 |
alert(msg) | 浏览器弹出警示框 |
console.log(msg) | 浏览器控制台打印输出信息 |
prompt(info) | 浏览器弹出输入框,用户可以输入 |
三、变量
1、作用:存放数据的容器
2、声明变量:var age = 10;
3、更新变量:var age = 10; age = 20;
4、声明多个变量:var age = 10, userName = "玉兔", address = "月亮"
5、特殊情况
情况 | 说明 | 结果 |
var age;console.log(age) | 只声明,不赋值 | undefined |
console.log(age) | 不声明,不赋值,直接用 | 报错 |
age=10;console.log(age) | 不声明,只赋值 | 10 |
6、命名规范
由字母、数字、下划线、$组成
严格区分大小写
不能以数字开头
不能出现关键字、保留字
变量名必须有意义
遵守驼峰命名法。首字母小写,后面单词首字母要大写
四、数据类型
js的变量数据类型只有在程序运行过程中根据等号右边的值来确定的。
js是动态语言,变量的数据类型是可以变化的
1、简单数据类型(基本数据类型)
简单数据类型 | 说明 | 默认值 |
Number | 数字型,包含整型和浮点型 | 0 |
Boolean | 布尔值类型,如true、false,等价于1、0 | false |
String | 字符串类型,如"王五" | "" |
Undefined | var a;声明了变量a,但不赋值,此时a=undefined | undefined |
Null | var a=null;声明了变量a为空值 | null |
1.1、在js中,八进制前面加0,十六进制前加0x
Number.MAX_VALUE最大值
Number.MIN_VALUE最小值
Infinity无穷大,-Infinity无穷小
NaN = Not a Number非数字=>isNaN()方法用来判断非数字,并返回一个布尔值,是数字返回false,非数字返回true
1.2、字符串嵌套遵从外双内单或外单内双
转义符 | 解释说明 |
\n | 换行符 |
\\ | 斜杠\ |
\t | tab缩进 |
\' | 单引号 |
\b | 空格 |
\" | 双引号 |
检测获取字符串的长度:变量名.length
字符串拼接使用 +(数值相加,字符相连)
在控制台中,数字打印出来是蓝色的,字符串打印出来是黑色的
1.3、布尔型有两个值:true,false
布尔型和数字型相加时,true为1,false为0
null NAN undefined '' 0 在转换为布尔值时为 false
1.4、underfined和字符串相加,结果是underfined字符串;underfined和数字相加,结果是NaN。
1.5、null和字符串相加是null字符串,和数字相加是数字本身
2、判断变量数据类型typeof(prompt取过来的值是字符型的)
3、数据类型的转换
3.1、转换为字符串
方式 | 说明 | 案例 |
toString() | 转成字符串 | var num=1;alert(num.toString()); |
String()强制转换 | 转成字符串 | var num=1;alert(String(num)); |
加号拼接字符串 | 和字符串拼接的结果都是字符串 | var num=1;alert(num+"我是字符串") |
3.2、转换为数字型
方式 | 说明 | 案例 |
parseInt(string)函数 | 将string类型转换为整数数值型 | parseInt('7') |
parseFloat(string)函数 | 将string类型转换为浮点数数值型 | parseFloat('7.1') |
Number()强制转换函数 | 将string类型转换为数值型 | Number('7') |
js隐式转换(- * /) | 利用算术运算隐式转换为数值型 | '1'-0 |
3.3、转换为布尔型
方式 | 说明 | 案例 |
Boolean()函数 | 其他类型转成布尔值 | Boolean('true') |
代表空、否定的值会转换成false,如' ' 0 NaN null undefined
其余值会转换成true
五、运算符
1、算术运算符
运算符 | 描述 | 案例 |
+ | 加 | 10+10=20 |
- | 减 | 10-10=0 |
* | 乘 | 10*10=100 |
/ | 除 | 10/10=1 |
% | 取余(取模) | 9%2=1 |
2、递增和递减运算符
递增++、递减--
放在变量前称前置递增或递减:++num 等价于num=num+1
放在变量后称后置递增或递减:num++ 等价于num=num+1
区别:前置自增和后置自增单独使用时,效果是一样的
前置:先自加,后运算
后置:先原值运算,后自加
3、比较运算符(两个数据进行比较,会返回一个布尔值作为运算结果)
运算符名称 | 说明 | 案例 | 结果 |
== | 等于(会转型) | 1==1 | true |
!= | 不等 | 1!=1 | false |
=== | 全等,数据类型和值一致 | 1==='1' | false |
3.1、 = 小结
符号 | 作用 | 用法 |
= | 赋值 | 把右边给左边 |
== | 判断 | 判断两边值是否相等(有隐式转换) |
=== | 全等 | 判断两边值和数据类型是否完全相等 |
4、逻辑运算符(常用于多个条件的判断)
逻辑运算符 | 说明 | 案例 |
&& | 逻辑与,and | true&&false |
|| | 逻辑或,or | true||false |
! | 逻辑非,not | !true |
逻辑与短路运算:如果表达式1结果为真,则返回表达式2;如果表达式1结果为假,则返回表达式1.【看假】(空或否定的为假--0 '' null undefined NaN)
逻辑或短路运算:如果表达式1结果为真,则返回表达式1;如果表达式1结果为假,则返回表达式2.【看真】
5、赋值运算符
赋值运算符 | 说明 | 案例 |
= | 直接赋值 | var userName='我是值'; |
+=、-= | 加,减一个数后再赋值 | var age=10;age+=5; //15 |
*=、/=、%= | 乘,除,取模后再赋值 | var age =2;age*=5; //10 |
六、运算符优先级
优先级 | 运算符 | 顺序 |
1 | 小括号 | ( ) |
2 | 一元运算符 | ++ -- ! |
3 | 算术运算符 | 先* / %后+ - |
4 | 关系运算符 | > >= < <= |
5 | 相等运算符 | == != === !== |
6 | 逻辑运算符 | 先&&后|| |
7 | 赋值运算符 | = |
8 | 逗号运算符 | , |
七、流程控制
1、顺序流程控制:按照先后顺序依次执行
2、分支流程控制
2.1、if多分支语法
if(条件表达式1){
执行语句1;
}elseif(条件表达式2){
执行语句2;
}else {
执行语句3;
}
2.2、三元表达式:条件表达式?表达式1:表达式2(如果条件表达式结果为真,则返回表达式1 的值,为假则返回表达式2的值)
2.3、switch语法
switch(表达式){
casevalue1:
执行语句1;
break;
...
default:
执行最后语句;
}
在开发中,表达式经常写成变量
表达式的值和value的值全等(值和值和数据类型都一致)
如果当前的case里没有break,则不会退出switch,继续执行下一个case
区别
switch case语句通常处理case比较确定值的情况;而if语句常用于范围判断
switch语句进行条件判断后直接执行程序的条件语句,效率更高;而if语句则需要依次判断
当分支较少时,使用if语句效率更高;当分支较多时,使用switch更好
3、循环结构
3.1、for循环
for(初始化变量;条件表达式;操作表达式){
循环体
}
补充:断点调试
浏览器--检查--source--找到需要调试的文件--在程序的某一行设置断点
watch:监视变量值的变化
按f11程序单步执行
双重for循环(循环嵌套)语法
for(外层的初始化变量;外层条件表达式;外层操作表达式){
for(里层的初始化变量;里层条件表达式;里层操作表达式){
执行语句
}
}
外层循环循环一次,里面的循环执行全部
3.2、while循环
while(条件表达式){
循环体
}
当条件表达式结果为真则执行循环体,否则退出循环
3.3、do ...while循环
do{
循环体
}while(条件表达式)
先执行一次循环体,再判断条件,当条件表达式结果为真则执行循环体,否则退出循环
4、continue
退出本次循环(当前次的循环),继续执行剩余次数的循环
5、break
退出当前整个循环
八、js命名规范以及语法格式
1、标识符命名规范
变量、函数的命名要有意义
变量一般用名词
函数一般用动词
2、操作符规范
操作符左右最好各保留一个空格
3、单行注释规范
单行注释最好空一格再写注释
九、数组
1、概念
一组有序数据的集合,其中每个数据被称为元素,在数组中可以存放任意类型的元素
2、创建数组
2.1、new
// var arr1 = new Array(); // 创建了一个空的数组
// var arr1 = new Array(2); // 这个2 表示 数组的长度为 2 里面有2个空的数组元素
vararr1=newArray(2, 3); // 等价于 [2,3] 这样写表示 里面有2个数组元素 是 2和3
2.2、数组字面量[ ]
vararr= [元素1,元素2,元素3]
3、获取数组元素
数组名[索引号] // 索引号从0开始
4、遍历数组
vararr= ['a','b','c'];
for(vari=0; i<arr.length; i++){
console.log(arr[i]);
}
arr.length动态监测数组长度
数组的长度是数组中元素的个数
数组中取不到值默认为undefined
5、数组中新增元素
5.1、修改length长度
arr.length=2;
5.2、修改索引号(推荐)
//第一种方法
arr[2] ='a';
//第二种方法,length是动态变化的
arr[arr.length] ='a';
• 索引号被占用,则是替换;没有占用,则是追加新元素
• 不要直接给数组名赋值
6、冒泡排序
vararr= [1,2,3,4,5];
for(vari=0;i<arr.length-1; i++){
for(varj=0;j<arr.length-i-1;j++){
if(arr[j] >arr[j+1]){
vartemp=arr[j];
arr[j] =arr[j+1];
arr[j+1] =temp;
}
}
}
7、检测是否是数组
// (1) instanceof 运算符 它可以用来检测是否为数组
vararr= [];
varobj= {};
console.log(arrinstanceofArray); // true
console.log(objinstanceofArray); // false
// (2) Array.isArray(参数); H5新增的方法 ie9以上版本支持
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false
8、添加、删除 数组元素
// 添加删除数组元素方法
// 1. push() 在我们数组的末尾 添加一个或者多个数组元素 push 推
vararr= [1, 2, 3];
// arr.push(4, 'pink');
console.log(arr.push(4, 'pink'));
console.log(arr);
// (1) push 是可以给数组追加新的元素
// (2) push() 参数直接写数组元素就可以了
// (3) push完毕之后,返回的结果是 新数组的长度
// (4) 原数组也会发生变化
// 2. unshift 在我们数组的开头 添加一个或者多个数组元素
console.log(arr.unshift('red', 'purple'));
console.log(arr);
// (1) unshift是可以给数组前面追加新的元素
// (2) unshift() 参数直接写数组元素就可以了
// (3) unshift完毕之后,返回的结果是 新数组的长度
// (4) 原数组也会发生变化
// 3. pop() 它可以删除数组的最后一个元素
console.log(arr.pop());
console.log(arr);
// (1) pop是可以删除数组的最后一个元素 记住一次只能删除一个元素
// (2) pop() 没有参数
// (3) pop完毕之后,返回的结果是 删除的那个元素
// (4) 原数组也会发生变化
// 4. shift() 它可以删除数组的第一个元素
console.log(arr.shift());
console.log(arr);
// (1) shift是可以删除数组的第一个元素 记住一次只能删除一个元素
// (2) shift() 没有参数
// (3) shift完毕之后,返回的结果是 删除的那个元素
// (4) 原数组也会发生变化
9、数组排序
// 2. 数组排序(冒泡排序)
vararr1= [13, 4, 77, 1, 7];
arr1.sort(function(a, b) {
// return a - b; 升序的顺序排列
returnb-a; // 降序的顺序排列
});
10、获取数组元素索引号
// 返回该数组元素的索引号 从前面开始查找,只返回第一个满足条件的索引号,如果在该数组里面找不到元素,则返回的是 -1
数组.indexOf(数组元素)
// 返回该数组元素的索引号 从后面开始查找
数组.lastIndexOf(数组元素)
这个方法可以用于数组去重,当索引号为-1时,就将这个数组的元素存入一个新的数组中,这样就可以得到一个元素不重复的新数组
11、数组转字符串
数组.toString() //将我们的数组转换为字符串
// join(分隔符)
vararr1= ['green', 'blue', 'pink'];
console.log(arr1.join()); // green,blue,pink
console.log(arr1.join('-')); // green-blue-pink
console.log(arr1.join('&')); // green&blue&pink
12、根据索引返回字符
// 1. charAt(index) 根据位置返回字符
// 2. charCodeAt(index) 返回相应索引号的字符ASCII值 目的: 判断用户按下了那个键
// 3. str[index] H5 新增的
varstr='andy';
13、拼接、截取字符串
// 1. concat('字符串1','字符串2'....)
varstr='andy';
console.log(str.concat('red')); //andyred
// 2. substr('截取的起始位置', '截取几个字符');
varstr1='改革春风吹满地';
console.log(str1.substr(2, 2)); // 第一个2 是索引号的2 从第几个开始 第二个2 是取几个字符
14、替换字符串
字符串.replace('被替换的字符', '替换为的字符') // 它只会替换第一个字符
15、字符串转数组
字符串.split('分隔符')
十、函数
1、概念
封装一段可以被重复执行调用的代码块,让大量代码重复使用
函数的封装就是把一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
2、函数的使用
//声明函数第一种方法--关键字
function函数名(){
函数体
}
//调用函数
函数名();
//声明函数第二种方法--函数表达式(匿名函数)
var变量名=function(){}
变量名();
函数不调用,自己不执行
函数名一般是动词
3、函数的参数
function函数名(形参1, 形参2){
函数体
}
函数名(实参1, 实参2);
形参接受实参,相当于一个变量
函数的参数可以有,可以没有,个数不限
3.1、函数形参和实参个数匹配
实参与形参一致,正常输出
实参多与形参,会取到形参的个数
实参少于形参,多余的形参就相当于一个变量没有赋值,默认为undefined
4、函数的返回值
function函数名(){
return需要返回的结果;
}
函数名();
函数名() = 返回的结果
return一次只能返回一个值,返回最后一个值
return终止函数:return后面的代码不会再执行
函数没有return,则返回undefined
5、arguments的使用
5.1、当不确定参数个数时,可以用arguments来获取
5.2、arguments是当前函数的一个内置对象,arguments对象中存储了所有传递的实参
5.3、arguments展示形式是一种伪数组
伪数组具有数组的length属性,
按照索引方式进行存储
没有真正数组的方法pop()、push()等
6、作用域
6.1、概念
代码名字在某个范围内起作用,目的是为了提高程序的可靠性,减少命名冲突
6.2、全局作用域
整个script标签,或者是一个单独的js文件中
6.3、局部作用域(函数作用域)
代码名字在函数内部起作用
6.4、全局变量
在全局作用域下的变量
在函数内部没有声明,直接赋值的变量也是全局变量(不推荐)
6.5、局部变量
在局部作用域下的变量
函数的形参也可以看做局部变量
6.6、从执行效率来看全局变量和局部变量
全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
局部变量 当我们程序执行完毕就会销毁, 比较节约内存资源
6.7、js(es5)中没有块级作用域
块级作用域{ }
6.8、作用域链
内部函数访问外部函数的变量,采取的是链式查找的方式去上一级作用域找,这种结构我们称为作用域链 (就近原则)
7、预解析
js引擎运行js 分为两步: 预解析 、代码执行
预解析: js引擎会把js 里面所有的 var 还有 function 提升到当前作用域的最前面
代码执行 :按照代码书写的顺序从上往下执行
预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升)
变量提升 就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作
函数提升 就是把所有的函数声明提升到当前作用域的最前面,不调用函数;函数表达式只会提升前面的变量名
预解析的时候函数的权重大于变量的权重
f1();
console.log(c);
console.log(b);
console.log(a);
functionf1() {
vara=b=c=9;
console.log(a);
console.log(b);
console.log(c);
}
// 以下代码
// function f1() {
// var a;
// a = b = c = 9;
// // 相当于 var a = 9; b = 9; c = 9; b 和 c 直接赋值 没有var 声明 当 全局变量看
// // 集体声明 var a = 9, b = 9, c = 9;
// console.log(a);
// console.log(b);
// console.log(c);
// }
// f1();
// console.log(c);
// console.log(b);
// console.log(a);
十一、对象
1、概念
对象是一组无序的相关属性和方法的集合
属性:事物的特征(常用名词)
方法:事物的行为(常用动词)
2、创建对象
对象属性名都是字符串或者是数字
通过变量名找到变量值
使用对象保存信息,结构更加清晰
2.1、字面量
//第一种
varobj= {
uname: '张三疯',
age: 18,
sex: '男',
sayHi: function() {
console.log('hi~');
}
}
// (1) 里面的属性或者方法我们采取键值对的形式 键 属性名 : 值 属性值
// (2) 多个属性或者方法中间用逗号隔开的
// (3) 方法冒号后面跟的是一个匿名函数
// 2. 使用对象
// (1). 调用对象的属性 我们采取 对象名.属性名 . 我们理解为 的
console.log(obj.uname);
// (2). 调用属性还有一种方法 对象名['属性名']
console.log(obj['age']);
// (3) 调用对象的方法 sayHi 对象名.方法名() 千万别忘记添加小括号
obj.sayHi();
//第二种
varobj1= {};
obj1.name="ls";
obj1.age=12;
obj1.gender="女";
obj1.sing=function(){
console.log("hello");
}
obj1['hobby'] ='学习';
console.log(obj1.name);
obj1.sing();
console.log(obj1);
注意:变量、属性、函数、方法的区别
变量和属性的相同点:他们都是用来存储数据的
变量 单独声明并赋值 ,使用的时候直接写变量名,单独存在
属性在对象里面的不需要声明的,使用的时候必须是 对象.属性
函数和方法的相同点 :都是实现某种功能 ,做某件事
函数是单独声明并且调用的 函数名() 单独存在的
方法在对象里面调用的时候 对象.方法()
2.2、new Object
varobj=newObject(); // 创建了一个空的对象
obj.uname='张三疯';
obj.age=18;
obj.sex='男';
obj.sayHi=function() {
console.log('hi~');
}
// (1) 我们是利用 等号 = 赋值的方法 添加对象的属性和方法
// (2) 每个属性和方法之间用 分号结束
console.log(obj.uname);
console.log(obj['sex']);
obj.sayHi();
2.3、构造函数
构造函数把对象里面一些相同的属性和方法抽象出来封装到函数里面
构造函数必须搭配new使用
function构造函数名(){
this.属性=值;
this.方法=function(){}
}
new构造函数名();
构造函数名首字母要大写
构造函数不需要return就可以返回结果
构造函数中的 return 如果是简单类型,覆盖不了 new 创建的对象,复杂类型可以把 new 创建的对象覆盖掉
3、new关键字执行过程
new 构造函数可以在内存中创建了一个空的对象
this 就会指向刚才创建的空对象
调用函数,执行构造函数里面的代码 ,给这个空对象添加属性和方法
返回这个对象给调用者
4、遍历对象
for (变量 in 对象){ }
5、对象的属性都是字符串
对象在调用toString()是会被转化成 [ object object ]
5、内置对象
5.1、内置对象是js提供的一些常用的或最基本而必要的功能
5.2、查文档
MDN(推荐)和W3C
5.3、Math对象
Math.PI // 圆周率
Math.floor() // 向下取整
Math.ceil() // 向上取整
Math.round() // 四舍五入版 就近取整 注意 -3.5 结果是 -3
Math.abs() // 绝对值
Math.max()/Math.min() // 求最大和最小值
5.4、日期对象
方法名 | 说明 |
getFullYear() | 获取年份 |
getMonth() | 获取月份 |
getDate() | 获取日期 |
getDay() | 获取星期几(周日0~周六6) |
getHours() | 获取时 |
getMinutes() | 获取分 |
getSeconds() | 获取秒 |
// 获得Date总的毫秒数(时间戳) 不是当前时间的毫秒数 而是距离1970年1月1号过了多少毫秒数
// 1. 通过 valueOf() getTime()
vardate=newDate();
console.log(date.valueOf()); // 就是 我们现在时间 距离1970.1.1 总的毫秒数
console.log(date.getTime());
// 2. 简单的写法 (最常用的写法)
vardate1=+newDate(); // +new Date() 返回的就是总的毫秒数
console.log(date1);
// 3. H5 新增的 获得总的毫秒数
console.log(Date.now());
5.5、数组对象
添加数组元素
方法名 | 说明 | 返回值 |
push() | 在末尾添加元素 | 返回新的长度 |
pop() | 删除最后一个元素 | 返回删除的元素的值 |
unshift() | 向数组开头添加元素 | 返回新的长度 |
shift() | 删除数组的第一个元素 | 返回第一个元素的值 |
数组排序
方法名 | 说明 |
reverse() | 倒序排列,无参数,改变原数组,返回新数组 |
sort() | 排序,改变原数组,返回新数组 |
vararr= [1, 64, 9, 6];
arr.sort(function(a, b) {
returnb-a; // 降a序
// return a - b; // 升序
});
数组索引
方法名 | 说明 | 返回值 |
indexOf('查找的元素',[起始位置]) | 查找给定元素的第一个索引 | 存在,返回索引号,否则返回-1 |
lastIndexOf() | 查找在数组中最后一个的索引 | 存在,返回索引号,否则返回-1 |
数组转换为字符串
方法名 | 说明 | 返回值 |
toString() | 把数组转换成字符串,逗号分割每一项 | 返回一个字符串 |
join('分隔符') | 把数组中的所有元素转换为一个字符串 | 返回一个字符串 |
截取数组
方法名 | 说明 | 返回值 |
slice(begin,end) | 数组截取从begin到end | 返回被截取的新数组 |
splice(a,b) | 数组从a删除,删除b个 | 返回被删除的新数组 |
5.6、字符串对象
(1)基本包装类型:String、Number、Boolean
(因为只有对象才有属性,所以js将简单类型包装成复杂数据类型,这样就可以使用这些属性)
(2)字符串的不可变
声明一个字符串,重新赋值的话,会在内存中新开辟一个地址,将变量指向新地址,原来的地址不会改变内容,所以程序不要大量使用拼接字符串
根据位置返回字符
方法名 | 说明 |
chartAt(index) | 返回指定位置的字符 |
chartCodeAt(index) | 获取指定位置的字符的Ascll码 |
str[index] | 获取指定位置字符 |
字符串操作方法
方法名 | 说明 |
concat(str1,str2...) | 拼接字符串,等价于 + |
substr(start,length) | 从start开始,length取得个数,不写第二个参数则是从 start 开始到最后一个结束 |
slice(start,end) | 从start开始,截取到end位置,end取不到 |
substring(start,end) | 从start开始,截取到end位置,end取不到,不接受负值 |
replace(str1,str2) | str1被替换的字符,str2替换的字符,返回新的字符串 |
split() | 将字符串切分为数组,并返回新数组 |
十二、数据类型
1、简单数据类型(基本数据类型或者值类型)
number String null undefined Boolean
null的返回值是Object,使用场景:如果声明一个对象,可以为其赋初始值
将值直接在栈中开辟一块内存存进去
函数中的形参也会在栈中开辟一块内存,存储地址
2、复杂数据类型(引用类型)
Array Object Function
在栈中开辟一块内存存储一个地址,在堆里面开辟一块内存存内容,栈中的地址指向堆里面的内容
引用类型在进行传参的时候传递的是地址
十三、webAPIs和js的关系
js == ECMAjavascript + DOM + BOM,
webApi == DOM + BOM