JS基础
一、学前准备
1.JS认识
js是解释性的语言,V8引擎
JS全称JavaScript。
设计目的:在静态页面的基础添加动态效果
由网景公司布兰登•艾奇设计开发,命名为JavaScript。当时,Java很火,网景想借用java的名气来推广,实际上,javaScript与java没有任何关系。
2. JS分成三部分
1)ES:ECMAScript,简称ES,称他为语法部分 ECMA:欧洲计算机制造商协会,制定了一套JS规则,JavaScript是对这套规则的具体体现
2)DOM:JS高级编程,DocumentObjectModel, 文档对象模型,用来操作页面的
3)BOM:BrowserObjectModel, 浏览器对象模型, 用来操作浏览器的
3.JS的运行环境
JS解释器
浏览器中集成了JS解释器
Node.js:集成了JS解释器
4.JS存在价值
1.在用户体验方面,功不可没
2.减轻服务器压力:相关的数据验证可以直接在客户端完成
5.JS引入方式
1.行内
2.内嵌
使用script标签引入js
<script>
</script>
3.外部引入
使用script标签的src属性引入js文件
<script src=""></script>
6.输出数据到控制台
console.log('日志');//用于调试代码,一次可打印多个数据到控制台
console.log('wu', '20', '女');
colsole.dir(new String('123');//打印详细信息
console.error('打印错误信息');
console.warn('警告信息');
console.info('普通信息');
7.事件三要素
事件就是js能监听到的页面上发生的所有动作
事件源:操作的对象
事件:动作
事件处理函数:要做的事情
语法:
事件源.事件 = function{
事件处理函数
}
如何拿到页面的标签: document.querySelector(‘标签’);
<style>
.light{
width: 100px;
height: 100px;
border-radius: 50%;
background-color: #ccc;
text-align: center;
}
</style>
<div class="light"></div>
<br>
<input type="button" value="开关">
<script>
// 获取页面标签,修改样式或内容
var count = 0
document.querySelector('input[type="button"]').onclick = function(){
count = count + 1;
var div1 = document.querySelector('.light');
if(count % 2 == 1){
div1.style.backgroundColor = '#f40';
div1.style.width = '150px';
div1.style.height = '150px';
div1.style.lineHeight = document.querySelector('.light').style.height;
div1.innerHTML = 'hhhhh...';
}else{
div1.style.backgroundColor = '#ccc';
div1.style.width = '100px';
div1.style.height = '100px';
div1.innerHTML = '';
}
}
</script>
二、基础语法
1.JS严格区分大小写
2.注释:单行注释和多行注释
//单行注释 Ctrl + /
/*
多行注释
快捷方式:Alt+Shift+A
*/
3.JS中的空格是用来排版的, 对语法没有影响
1.变量
变量是用来缓存数据的
变量的声明:
1). 使用var来声明变量
2). 使用字母、数字、下划线、$来命名,不能使用数字开头,不要使用保留字
3). 严格区分大小写;
4). 命名一定要做到见名知意
5). 使用的变量必须声明,否则报错
6). 使用=给变量赋值
变量声明提升:将变量的声明提升至最前方(在声明前可以访问变量,值为undefined)
2.变量的类型
js属弱类型语言,声明时不需要定义类型,类型会在赋值时确定,并且可以随时改变
使用typeof获取变量的类型
2.1 基础类型
1).数字类型
不区分整数、小数、实点数等,都是number
JS不适合进行科学计算,小数运算精度丢失
console.log(0.1 + 0.2);//精度丢失
//解决办法
console.log((0.1*10 + 0.2*10) / 10);//推荐
console.log((0.1 + 0.2).toFixed(1));//保留两位小数
NaN: Not a Number, 不是一个数字,但是类型是Number,NaN不等于任何值,包括它自己
parseInt:把一个数字转换为整数
2)字符串: 文本类型
定义:用引号(单引号、双引号、反引号)引起来的
单引号号里面放单引号,双引号里面放双引号,只用反斜杠转义。
反引号支持引入变量(模板字符串)
var stuname = '尔尔er';
var gender = '女';
var $age = 20;
var mydesc = `我是${stuname}, 性别${gender}, 年龄${$age}`;
其他类型转字符串类型:
转型函数String()
toString()方法
隐式转换:字符串拼接时
字符串的数学运算
减乘除:
都是数学运算,遇到非数字类型,需基于Number将其转换为数字类型后,再进行运算
加:
字符串在进行+运算时,优先考虑字符串
- 数学运算
- 字符串拼接,只要加号两边任意一边出现字符串,则变为字符串拼接
传统拼接方式
var name = '尔尔er';
var age = 10;
var str = '我叫' + name + ', 今年' + age + '岁';
3) 布尔boolean类型
true和false两个值
var b1 = true;
var b2 = false;
console.log(typeof b1);
4) undefined 类型
返回undefined的情况:
1)声明的变量没有赋值时
2)访问数组不存在的下标或对象没有的属性
3)函数没有返回值时,返回值为undefined
4)没有给形参传实参时
5) Typeof一个没有声明的变量
5) null 类型
值为null,Typeof null返回的是Object
console.log(typeof null);//object
/*JS里面的一切皆为对象,万物皆空*/
console.log(null == undefined);//true
console.log(null === undefined);//false, 值相同类型不同
基础变量类型的特征
1.值不可以改变
var num = 100;
num = 200;
console.log(num);//200
/*100占用了内存空间,但是变量不再引用她,会浪费内存的情况,
JS解释器会进行垃圾回收:去检查该内存块还有没有引用,如果不存在对这个内存块数据的引用,也就是引用数
为0,就释放内存(GC)*/
2.2 引用类型
添加链接描述
1) 数组
数组本质上是对象,是对象的一种特殊表现
是一类数据的集合,比如学生姓名、性别、年龄等
var arr = ['wu', '女', 20];
console.log(arr);
console.log(arr[2]);
数组里面的每一个单元叫元素,数组的下标从0开始
二维数组
var arr = [[1,2,3],[4,5,6],[7,8,9]];
console.log(arr[1][1]);//2
数组中的元素可以是任意类型,也可以是数组
数组的常用方法
2) 对象
对象用于描述一个事务
//创建对象
var obj = {
name: '尔尔er',
age: 20,
gender: 'female'
};
//使用 对象.属性名 获取对应的值
console.log(obj.name);
//使用 对象['属性名'] 获取属性对应的值, 支持表达式
console.log(obj['age']);
var a = 'gender';
console.log(obj[a]);
JSON格式的数据
本质上就是个对象
var result = {
code: 1,
error: 0,
data: [{
title: '冰箱',
price: 8000,
sku: 899,
keywords: ['冷冻', '保鲜']
},{
title: '冰箱1',
price: 8000,
sku: 899,
keywords: ['冷冻', '保鲜']
},{
title: '冰箱2',
price: 8000,
sku: 899,
keywords: ['冷冻', '保鲜']
}]
};
console.log(result.data[1].keywords[0]);
3) 函数
function 函数名(形参){
函数体;
}
函数调用:
函数名后面跟小括号表示函数的执行, 使用return返回函数的执行结果。如果函数没有return返回值,那么 它的返回值为undefined
function sum(m, n){
return m + n;
}
var result = sum(1, 2);
console.log(typeof sum);//function
函数表达式
var fun = function(a){
console.log(a);
}
fun();//调用
2.3 基本数据类型和引用数据类型的区别
JS中的变量都是保存在栈内存中的,基本数据类型的值直接在栈内存中存储,值与值之间独立存在,修改一个变量不会影响其他变量。
var num1 = 100;
var num2 = num1;
num1 = 200;
console.log(num2);//100
引用类型对象是保存在堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址(对象的引用)。如果两个变量保存的是同一个对象引用。当通过一个变量修改属性时,另一个也会受到影响。
var arr1 = [1, 2, 3, 4];
var arr2 = arr1;
console.log(arr1 == arr2);//true
arr2[1] = 200;
console.log(arr1[1]);//200
var a = [1,2,3];
var b = [1,2,3];
console.log(a == b);
var a1 = [4,5,6];
var b1 = a1;
//重新赋值会创建一片新的内存空间
a1 = [7,8,9];
console.log(b1[2]);
2.4 数据类型之间的转换
1)数字转字符串
- 使用toString方法,undefined没有toString方法
- 后面加空字符串
- 使用转型函数String()
var a = 100;
console.log(a);
console.log(a.toString());
console.log(a + '');
console.log(String(a));
2)字符串转数字
- 变量除1或乘1
- 使用转型函数Number()0
- 处理整数时使用parseInt()函数
- parseFloat()将字符串转换为浮点数
var str = "13";
console.log(str/1);//隐式转换
console.log(Number(str));
console.log(parseInt(str));
转换规则:
1.看起来是数字的就转为数字,反之转换为NaN;
2. 将整数部分转为数字,遇到不是数字的字符则停止转换
3. 将字符串转为数字, 遇到非数字字符则停止转换,第一个小数点除外
3) 转换成布尔类型
非0为真,非空为真
- 使用转型函数Boolean
- 使用非运算
var num = 10;
var num1 = 0;
console.log(Boolean(num)); // true
console.log(Boolean(num1));// false
console.log(Boolean(NaN));// false
console.log(Boolean(Infinity));// true
console.log(Boolean(''));// false
console.log(Boolean(' '));// true
console.log(Boolean(null));//false
console.log(Boolean(undefined));//false
console.log(!![]);//true
console.log(!!{});//true
5.变量的作用域和作用域链
全局变量:在顶层代码里声明的变量。全局变量的作用域是全局的,网页的所有脚本和函数都可以访问到。
局部变量:在函数内部声明的变量,局部变量的作用域是局部的,只能在函数内部访问。
块级作用域:ES6里面的{里面使用let声明的变量,var声明的变量不存在块级作用域。}
变量提升:只提升声明,不提升赋值。
JJS解释器执行js代码的步骤:
1)语法检查:
2)预编译:
①全局预编译:
i. 创建一个GO对象,GlobalObject,执行期上下文
ii. 把声明的全局变量作为属性追加到该对象里
iii. 把函数声明作为对应的属性值
②局部预编译:在调用函数时刻才开始预编译AO
i. 创建一个AO对象,即ActiveObject,函数的执行期上下文
ii. 把函数内部声明的变量、函数名和形参作为AO属性名,值为undefined
iii. 把实参的值赋值给对应的属性
iv. 把函数内部声明的函数作为值赋值给对应的属性
3)执行语句
作用域链:变量的取值一般是在声明这个变量的函数内部查找,如果找不到,则会沿着作用域链一级一级向上查找。
6.运算符
比较运算符
.>、<、>=、<=
若一个值为数字,一个值为字符串,则将字符串转为数字进行比较。
若两个值都为字符串,则比较编码大小
console.log(10 > 20);//false
console.log(10 < 20);//true
console.log(10 >= 20);//false
console.log(10 <= 20);//true
console.log(10 > '11');//false
console.log("21" > "111");//true
console.log("A" > "a");//false
==、!=
相等时判断变量值是否相等,在判断是否相等时,规定undefined与null的结果为true。判断对象与对象是否相等时主要看空间地址,地址相同则相等。NaN和其他值永不等,包括它自己。
console.log("--------相等---------");
console.log(10 == 10);//true
console.log(10 == "10");//true
console.log(0 == true);//false
console.log(0 == null);//false
console.log(undefined == null);//true 规定
console.log(0 == undefined);//false
console.log(10 != 10);//false
console.log(10 != "10");//false
console.log(0 != true);//true
console.log(0 != null);//true
console.log(undefined != null);//false
console.log(0 != undefined);//true
全等===、不全等!==
判断数据类型及变量值是否相等,全等不会发生类型转换
console.log(10 === 10);//true
console.log(10 === "10");//false
console.log(0 === true);//false
console.log(0 === null);//false
console.log(undefined === null);//false
console.log(0 === undefined);//false
console.log("--------不全等--------");
console.log(10 !== 10);//false
console.log(10 !== "10");//true
console.log(0 !== true);//true
console.log(0 !== null);//true
console.log(undefined !== null);//true
console.log(0 !== undefined);//true
逻辑运算符
其他类型转布尔值:
非0为真,非空为真。 null,undefined为false。引用数据类型 true
逻辑非!
返回值为布尔值,其他类型的变量逻辑非会将其转换为布尔值,再求反
console.log(!1);//false
console.log(![]);//false
console.log(!null);//true
console.log(!undefined);//true
console.log(!'');//true
console.log(!0);//true
!!可将其他类型转换为布尔值
console.log(!!1);//true
console.log(!![]);//true
console.log(!!null);//false
console.log(!!undefined);//false
console.log(!!'');//false
console.log(!!0);//false
逻辑与&&
一假全假 全真则真
console.log(true && true);//true
console.log(true && false);//false
console.log(false && true);//false
console.log(false && false);//false
第一个操作数为真,则返回第二个操作数的值
第一个操作数为假,则返回第一个操作数的值
console.log(true && 1);//1
console.log(false && 1);//false
console.log(1 && 2);//2
console.log(0 && 2);//0
console.log(null && 2);//null
console.log([] && 2);//2
console.log([null] && 2);//2
console.log([null] && null);//null
console.log(1 && 2 && 3);//3
console.log(1 > 2 && 2);//false
console.log("abc" && 2 && false);//false
逻辑或||
一真全真 全假则假
console.log(true || true);//true
console.log(true || false);//true
console.log(false || true);//true
console.log(false || false);//false
第一个操作数为真,则返回第一个操作数(表达式)的值
第一个操作数为假,则返回第二个操作数的值
console.log(true || 1);//true
console.log(false || 1);//1
console.log(1 || 2);//1
console.log(0 || 2);//2
console.log(null || 2);//2
console.log([] || 2);//[]
console.log([null] || 2);//[null]
console.log([null] || null);//[null]
自加、自减
var n = 1;
console.log(n++);//1
console.log(++n);//3
//区别:n++是先执行打印语句,再自加,++n是先自加,再执行打印
逗号运算符
逗号操作符会返回表达式的最后一项
var num =(1,2,3,4)
console.log(num)//4
var a =1, b=2;
var bool(a>0,b>3);
console.log(bool);//false
in运算符
既可以判断自身的属性,也可以判断继承来的属性
hasOwnProperty
只能判断自身有的属性,不能判断继承来的属性
propertyIsEnumerable()
检查一个属性是否属于某个对象自有属性,不包括继承来的属性,且该属性可枚举
//检测属性
var person = {name:"尔尔er", age: 20}
//设置属性,并配置信息
Object.defineProperty(person, "sex",{
value:"女",
enumerable:false
});
//in
console.log('name' in person);//true
console.log('sex' in person);//true
console.log('toString' in person);//true
//hasOwnProperty()
console.log(person.hasOwnProperty('name'));//true
console.log(person.hasOwnProperty('sex'));//true
console.log(person.hasOwnProperty('toString'));//false
//propertyIsEnumerable()
console.log(person.propertyIsEnumerable('name'));//true
console.log(person.propertyIsEnumerable('sex'));//false
console.log(person.propertyIsEnumerable('toString'));//false
instanceof:用于判断某个对象是否是某个构造函数的实例化
eval
可以在里面直接执行js代码
三目运算符
表达式?结果1:结果2
求表达式的结果:布尔值的值为真取结果1返回,值为假取结果2返回
console.log(1 ? "123":"456");
三目运算符中可以嵌套三目运算符
instanceof运算符
判断一个对象是否是某个构造函数的实例化对象
var obj = {};
console.log(obj instanceof Object);
赋值运算符
=、*=、+=、-=、/=、%=
var a = 1;
a += 3;// a = a + 3;
7.语句
js语句建议使用分号作为结束符
if语句
当条件为true时,执行if中的语句,否则执行else中的语句
if(判断条件){
//布尔表达式结果为true则执行
代码块;
}
if("1" == 1){
console.log("相等");
}
var age = 12;
if(age >= 70){
console.log("老年");
}else if(age < 70 && age >=18){
console.log("成年人");
}else{
console.log("未成年");
}
switch语句
当switch括号内部表达式的结果和case的值进行匹配,当值和类型都相等时,才会进行匹配。
使用break来阻止运行下一个case。没有break的话,会出现穿透效果,不执行匹配,直接去执行后面的代码。
switch(表达式){
case 1:
//代码块
break;
case 2:
//代码块
break;
......
default:
break;
}
var score = 50;
switch(score/10){
case 1:
case 2:
case 3:
case 4:
case 5:
console.log("不及格");
break;
case 6:
case 7:
console.log("及格");
break;
case 8:
case 9:
console.log("优秀");
break;
}
小案例:
//根据用户输入的年份和月份判断当月有多少天
var year = Number(prompt('请输入年份'));
var month = Number(prompt('请输入月份'));
switch(month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
console.log('31天');
break;
case 4:
case 6:
case 9:
case 11:
console.log('30天');
break;
case 2:
if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){
console.log('29天');
}else{
console.log('28天');
}
break;
default:
console.log('数据有误');
break;
}
for循环
for(表达式1;表达式2;表达式3)
表达式1:用于定义变量并赋值,在循环之前执行
表达式2:每次循环前的判断条件,结果为true则执行循环,否则不执行
表达式3:每次循环结束后,更改变量的值,使其判断条件可能为假,跳出循环
for(var i = 0; i < 10; i++){
console.log(i);
}
for(var i = 0, j = 0; i < 5, j < 8; i++,j++){
console.log(i,j);
}
死循环
for(;;){
console.log(1);
}
break和continue可用在for循环中,break终止当前循环,continue跳出本次循环,继续执行。
for (var i = 0; i < 10; ++i){
if(i == 5){
break;
}
console.log(i);//0 1 2 3 4
}
for (var i = 0; i < 10; ++i){
if(i = 5){
continue;
}
console.log(i);// 0 1 2 3 4 6 7 8 9
}
for…in
用于遍历对象的属性名称,数组也是对象。for in会遍历数组或对象所有的可枚举属性,包括从原型中继承来的属性原型
遍历数组时获取到的索引值为字符串类型。不建议使用for…in遍历数组
Object.prototype.method=function(){
}
var obj = {
name:'尔尔er',
age: 18,
gender: 'female'
}
for (var key in obj) {
console.log(key);//name age gender
console.log(obj[key]);// '尔尔er' 18 female
}
Array.prototype.method=function(){
}
var arr = ['monkey', 'dog', 'cat'];
for(var a in arr){
console.log(a);
console.log(arr[a]);
}
while
先判断再执行
var a = 1;
var sum = 0;
while(n < 11){
sum += n++;
}
console.log(sum);
do…while
先执行再判断
var m = 3;
var n = 10;
do{
console.log('hhhhh');
}while(m > n);
try…catch
try{
console.log(a);
}catch(error){
// try里面的代码报错才会执行catch
console.log(error.message);
}finally{
// 报不报错都会执行
console.log('我总会执行...');
}
8.类和对象
类:类是对事物的抽象(如:人类)
对象:类的实例化(如:人类中的张三)
属性:对象的特征(如:年龄,性别)
方法:对象的动作称为方法(如:吃、睡)