目录
文章目录
1. 初识js
1.1 浏览器执行js简介
1.2 js的组成
1.3 js初体验
- js的三种书写位置
1.4 js注释
- 单行注释:加上//
- 多行注释:/* 注释内容 */
1.5 js输入输出语句
// 1. 输入框
prompt('请输入你的年龄')
// 2. alert警示框
alert('计算的结果是')
// 3. 控制台输出:给程序员测试用的
console.log('这是程序员能看到的')
2. 变量
2.1 什么是变量
- 变量是用于存放数据的容器,我们通过变量名获取数据,设置数据可以修改。
- 本质:变量是程序在内存中申请的一块用来存放数据的空间。
2.2 变量的使用
变量在使用的时候分为两步:
- 声明变量
var age; // 声明一个名称为age的变量
- 赋值
age = 18;
以上两步可以合二为一,即声明一个变量并赋值,我们称之为变量的初始化
var age = 18;
2.3 案例:保存用户的输入信息
<script>
// 1. 用户输入姓名,存储到myname的变量中
var myname = prompt('请输入姓名');
// 2. 输出用户的姓名
alert(myname);
</script>
2.4 变量语法扩展
- 一个变量被重新赋值后,原有的值被覆盖,变量值将以最后一次赋值为准
- 可以同时声明多个变量,注意使用逗号隔开
var age = 18, addredd = 'beijing', gz = 2000;
- 声明变量的特殊情况
- 只声明不赋值,结果是‘undefined’
- 不声明不赋值,直接拿来使用,会报错
// tel为没有声明也没有赋值的变量 console.log(tel);
- 不声明只赋值,可以使用,但是不提倡这么使用
2.5 变量的命名规范
- 由字母,数字,下划线,美元符号组成
- 严格区分大小写
- 不能以数字开头
- 不能是关键字,保留字
- 变量名必须有意义
- 遵守驼峰命名法:首字母小写,后面单词的首字母需要大写
- 一般不用name作为变量名
3. 数据类型
3.1 数据类型简介
- js的变量类型是在程序运行过程中根据等号右边得值来确定的
- js是动态语言,变量的数据类型是可以变换的
- 数据类型分类:简单数据类型(Humber, String, Boolean, Undefined, Null),复杂数据类型(Object)
3.2 数字型Number
// 1. 八进制:数字前面加上0表示八进制
var num1 = 010; // 表示八进制8
// 2. 十六进制:数字阿前面加上0x表示十六进制
var num2 = 0xa; // 表示十进制10
// 3. 数字型的最大值和最小值
console.log(Number.MAX_VALUE);
console.log(Number.MIN_VALUE);
// 4. 三个特殊值:无穷大,无穷小,非数值
console.log(Number.MAX_VALUE * 2); // Infinity
console.log(-Number.MAX_VALUE * 2); // -Infinity
console.log('pink' - 100); // NaN: Not a number
// 5. isNaN() 这个方法用来判断非数字 返回true和false
console.log(isNaN(12)); // false
console.log(isNaN('pink')); // true
3.3 字符串类型String
-
加了引号就是字符串类型
-
单或双引号都可,推荐使用单引号, 因为html标签里面的属性使用的是双引号
-
若字符串里面要有引号,遵循外单内双或者外双内单
-
转义符
-
字符串长度:length属性
var str = 'my name is andy'; console.log(str.length); // 15
-
字符串拼接:用+号
注意:只要有字符串与其他类型拼接,其类型为字符串类型
3.4 布尔型Boolean
var flag = true;
var flag1 = false;
console.log(flag + 1); // 2, 说明true参与加法运算当1来看
console.log(flag1 + 1); // 1, 说明false参与加法运算当0来看
3.5 未定义数据类型Undefined
var str;
comsole.log(str); // Undefined
var str2 = Undefined; // Undefined
console.log(str2 + 'pink'); // Undefinedpink 任何数据类型和字符串拼接都会变成字符串
console.log(str2 + 1); // NaN
3.6 空值null
var space = null;
console.log(space + 'pink'); // nullpink
console.log(space + 1); // 1 此处区别于Undefined
3.7 获取变量数据类型
- typeof可以用来检测数据类型
var num = 10; console.log(typeof num); // number // 注意:prompt取过来的值是字符型的 var age = prompt('请输入您的年龄'); console.log(age); console.log(typeof age); // string
- 也可以通过f12查看控制台输出的数据的颜色来判断数据类型
3.8 字面量
字面量是在源代码中一个固定值的表示法,就是如何表达这个值
- 数字字面量:8, 9, 10
- 字符串字面量:‘黑马’, ‘程序员’
- 布尔字面量:true, false
3.9 数据类型转换
-
转换为字符串类型
-
转换为数字型(前两个方法最常用)
var age = prompt('请输入您的年龄'); // 1. parseInt(变量) 得到的是整数 console.log(parseInt(age)); // 2. parseFloat(变量) 得到的是浮点数 console.log(parseFloat('3.14')); // 3.14 // 3. 利用Number(变量) var str = '123'; console.log(Number(str)); // 123 // 4. 利用了算数运算 - * / 隐式转换 console.log('12' - 0); // 12 console.log('123' - '120'); // 3 console.log('123' * 1); // 123
-
转换为布尔型
// 下面五个都是false,其他都是true console.log(Boolean('')); console.log(Boolean(0)); console.log(Boolean(NaN)); console.log(Boolean(null)); console.log(Boolean(undefined));
4. 运算符(操作符)
4.1 算术运算符
- 加减乘除取模±*/%
- 浮点数的精度问题:17位,但在算数计算时其精度远远不如整数,所以不要直接判断两个浮点数是否相等
var num = 0.1 + 0.2; console.log(num); // 0.30000000000000004 console.log(0.07 * 100); // 7.000000000000001
4.2 递增和递减运算符
- ++num先自加后取返回值
- num++先取返回值后自加
4.3 比较运算符
- < > <= >= == !=
- ===全等 要求值和数据类型都一致
console.log(18 == '18'); // true console.log(18 === '18'); // false
4.4 逻辑运算符
- &&与 !!或 !非
4.5 赋值运算符
- = += -= *= /= %=
5. 流程控制
流程控制主要有三种结构,分别是顺序结构、分支结构和循环结构,代表三种代码执行的顺序。
5.1 分支结构
// 1. if elseif else
// 2. 表达式1 ? 表达式2 : 表达式3
// 3. switch
switch(表达式) {
case value1:
// 表达式等于value1时要执行的代码
break;
case value2:
// 表达式等于value2时要执行的代码
break;
default:
// 表达式不等于任何一个value时要执行的代码
}
6. 数组
// 1. 用new创建一个新数组
var arr = new Array();
// 2. 利用数组字面量创建数组
var arrStus = ['xiaobai', 12, true, 28.9]
// 注意:数组里面可以存放任意类型的数据
// 3. 利用索引获取数组中的元素
alert(arrStus[1]); // 获取第2个元素
// 4.获取数组长度
alert(arrStus.length); // 4
// 5. 数组中新增元素
// 方法一:length属性是可读写的,可以通过修改length来达到扩容的目的
// 空值默认值为undefined
arrStus.length = 7; // arrStus = ['xiaobai', 12, true, 28.9, empty*3]
// 方法二:可以通过修改数组索引的方式追加数组元素
arrStus[4] = 'name';
7. 函数
- 基本知识
// 1. 声明函数
function getSum(num1, num2){
// 函数体代码
console.log(num1 + num2);
return 666;
}
// 2. 调用函数
console.log(getSum(1, 3));
// 3. 返回值
// return只能返回一个值,如果逗号隔开多个值,以最后一个为准
return 666, 777; // 返回的是777
// 如果没有return 则返回 undefined
-
arrguments
-
匿名函数:类似于定义变量的写法,var 变量名 = function(){}; 调用的方式为变量名();
8. 作用域
- 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存。
- 局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销
毁,因此更节省内存空间。 - js没有块级作用域,也就是说,在if语句、循环语句中创建的变量,在if语句和循环语句外也能使用。
if (true) { var num = 123; console.log(num); // 123 } console.log(num); // 123
9. 预解析
- 预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明的变量在内存中进行提前声明或者定义。预解析会把变量和函数的声明在代码执行之前执行完成。
- 变量预解析:变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。
- 函数预解析:函数的声明会被提升到当前作用域的最上面,但是不会调用函数。
- 注意:对于匿名函数,其是由变量创建的,所以仅有声明提前,fn在提升之后的值是undefined。若fn调用是在fn被赋值为函数体之前,此时fn的值是undefined,所以无法正确调用。
fn(); // 不能执行 var fn = function() { console.log('12'); } fn(); // 可以执行
10. 对象
10.1 创建对象
- 使用对象字面量创建对象:就是花括号 { } 里面包含了表达这个具体事物(对象)的属性和方法;{ } 里面采取键值对的形式表示。
var star = { name : 'pink', age : 18, sex : '男', sayHi : function(){ alert('大家好啊~'); } }; console.log(star.name) // 调用名字属性 console.log(star['name']) // 调用名字属性 star.sayHi(); // 调用 sayHi 方法,注意,一定不要忘记带后面的括号
- 利用 new Object 创建对象。
var andy = new Object(); // 此时创建的是空对象 // 通过对象操作属性和方法的方式,来为对象增加属性和方法 andy.name = 'pink'; // 也可以 andy[name] = 'pink'; andy.age = 18; andy.sex = '男'; andy.sayHi = function(){ alert('大家好啊~'); }
- 利用构造函数创建对象:构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
注意:构造函数约定首字母大写。// 1. 构造函数的封装格式 function 构造函数名(形参1,形参2,形参3) { this.属性名1 = 参数1; this.属性名2 = 参数2; this.属性名3 = 参数3; this.方法名 = 函数体; } // 2. 构造函数的调用格式 var obj = new 构造函数名(实参1,实参2,实参3);
10.2 遍历对象
- 使用for…in语句。for…in 语句用于对数组或者对象的属性进行循环操作。
// 遍历对象 var people = { name: 'pink', age: 18, sex: 'man', fn: function () {} } // for in遍历对象 // for in里面的变量我们喜欢写k或者key for (var k in people) { console.log(k); // k得到的是属性名,即name age sex fn console.log(people[k]); // people[k]得到的是属性值,即 pink 18 man f(){} }
11. 内置对象
- 内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)。
- JavaScript 提供了多个内置对象:Math、 Date 、Array、String等
- 查阅文档:MDN https://developer.mozilla.org/zh-CN/
- 常用的内置对象:Math,日期,数组,字符串
11.1 Math对象
- Math 对象不是构造函数,它具有数学常数和函数的属性和方法。跟数学相关的运算(求绝对值,取整、最大值等)可以使用 Math 中的成员。
Math.PI // 圆周率 Math.floor() // 向下取整 Math.ceil() // 向上取整 Math.round() // 四舍五入版 就近取整 注意 -3.5 结果是 -3 Math.abs() // 绝对值 Math.max()/Math.min() // 求最大和最小值 // 随机数方法 function getRandom(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
11.2 日期Date对象
-
Date是一个构造函数,所以我们需要实例化后才能使用。Date实例用来处理日期和时间。
// 1. 获取当前时间 // 如果括号里面有时间,则返回参数的时间,如new Date('2019-5-1') 或者 new Date('2019/5/1')。没参数则返回当前时间。 var now = new Date(); console.log(now); // Fri Jul 28 2023 18:24:32 GMT+0800 (China Standard Time) console.log(now.getFullYear()); // 2023 console.log(now.getDay()); // 5 console.log(now.getMinutes()); // 30
-
日期格式化
案例:封装一个函数得到15:05:10这种格式的时间
-
获取日期的总的毫秒数(时间戳)
注意:获取的是距离1970年1月1日过了多少毫秒数var date = new Date(); // 1. 通过valueOf和getTime获取 console.log(date.valueOf()); console.log(date.getTime()); // 2. 简单写法(也是开发中最常用的写法) var date1 = +new Date(); // +new Date()返回的就是总的毫秒数 console.log(date1); // 3. H5新增的方法 console.log(Date.now());
11.3 数组对象
-
检测是否为数组有两种方法。一是使用instanceof 运算符,可以判断一个对象是否属于某种类型;二是Array.isArray()用于判断一个对象是否为数组,isArray() 是 HTML5 中提供的方法。
var arr = [1, 23]; var obj = {}; console.log(arr instanceof Array); // true console.log(obj instanceof Array); // false console.log(Array.isArray(arr)); // true console.log(Array.isArray(obj)); // false
-
删除数组元素
var arr = []; arr.push(12);
-
数组排序
sort的参数:sort(); sort(compareFn);
compareFn为定义排序顺序的函数。返回值应该是一个数字,其正负性表示两个元素的相对顺序。该函数使用两个用于比较的参数。
如果没有compareFn,所有非 undefined 的数组元素都会被转换为字符串,并按照 UTF-16 码元顺序比较字符串进行排序。例如“banana”会被排列到“cherry”之前。在数值排序中,9 出现在 80 之前,但因为数字会被转换为字符串,在 Unicode 顺序中“80”排在“9”之前。所有的 undefined 元素都会被排序到数组的末尾。
// 1. 不带参数 const array1 = [1, 30, 4, 31, 9, 100000, 100, 10]; array1.sort(); console.log(array1); // Array [1, 10, 100, 100000, 30, 31, 4, 9] // 2. 带参数 var arr2 = [1, 30, 4, 21, 100000]; arr2.sort(function (a, b) { return b - a; // 降序,return a - b;为升序 }) console.log(arr2);
-
数组索引方法
var arr3 = [1, 34, 23, 43, 34, 9, 78]; console.log(arr3.indexOf(34)); // 1 console.log(arr3.lastIndexOf(34)); // 4
-
数组转换为字符串
console.log(arr5); // ['c', 'a', 'z', 'x', 'b'] console.log(arr5.toString()); // c,a,z,x,b console.log(arr5.join('|')); // c|a|z|x|b
-
concat(), slice(), splice()
// 1. concat() 拼接数组 var arr6 = arr3.concat(arr5); // arr6 = arr3 + arr5 var numbers = num1.concat(num2, num3); // numbers = num1 + num2 + num3 // 2. slice() 数组截取函数 console.log(arr6.slice(1, 4)); // 反水被截取的新数组 // 3. splice() 数组删除(第几个元素(下标)开始,要删除的个数) arr6.splice(1, 2);
11.4 字符串对象
-
基本包装类型
为了方便操作基本数据类型,JavaScript 还提供了三个特殊的引用类型:String、Number和 Boolean。基本包装类型就是把简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法。 -
字符串的不可变性
指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。var str = 'abc'; str = 'hello'; // 当重新给 str 赋值的时候,常量'abc'不会被修改,依然在内存中 // 重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变 // 由于字符串的不可变,在大量拼接字符串的时候会有效率问题 var str = ''; for (var i = 0; i < 100000; i++) { str += i; } console.log(str); // 这个结果需要花费大量时间来显示,因为需要不断的开辟新的空间
-
根据字符返回位置,indexOf有两个参数,第二个参数默认为0
注意:字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串。
-
根据位置返回字符
var str = 'changxiangsi'; console.log(str.charAt(1)); console.log(str.charCodeAt(2)); console.log(str[1]);
-
字符串操作方法
-
replace()
该方法用于在字符串中用一些字符替换另一些字符。但是不会更改源字符串。var str2 = 'xianglio'; console.log(str2.replace('o', 'u')); // xiangliu // replace 并不更改源字符串 console.log(str2); // xianglio
-
split() 字符串转化为数组,前面学过join把数组转化为字符串
var str3 = 'red,pink,blue'; console.log(str3.split(',')); // ['red', 'pink', 'blue'] var str4 = 'red&pink&blue'; console.log(str4.split('&')); // ['red', 'pink', 'blue']
-
toUpperCase() 转换大写 toLowerCase() 转换小写
console.log('alphabet'.toUpperCase()); // 'ALPHABET'
-
案例:统计出现次数最多的字符
// 判断对象中有某个属性的方法 var o = { age: 18 } if (o['age']) { console.log('里面有该属性'); } else { console.log('没有该属性'); } // 求字符串中出现次数最多的字符 // 1. 将每个字符出现的次数存入一个对象中 var str = 'abcoefoxyozzopp'; var obj = new Object(); for (var i = 0; i < str.length; i++) { var char = str.charAt(i); if (obj[char]) { obj[char]++; } else { obj[char] = 1; } } // 2. 遍历对象, 找到数值最大的属性 var max = 0; var mchar = ''; for (var k in obj) { if (obj[k] > max) { max = obj[k]; mchar = k; } } console.log(obj); console.log('字符:' + mchar); console.log('次数:' + max);
12. 简单数据类型和复杂数据类型
- 简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。
- 值类型:在存储时变量存储的是值本身,如string, number, boolean, undefined, null。简单数据类型是存放到栈里面的,直接开辟一个空间存放其值。
- 引用类型:在存储时变量中存储的仅仅是地址(引用),通过new关键字创建的对象(系统对象,自定义对象),如Object, Array, Date等。复杂数据类型首先在栈里面存放地址,用十六进制表示,然后这个地址指向堆里面的数据。
- 简单数据类型传参:直接把值传过去,不会对原本的变量产生影响。
- 复杂数据类型传参:传的是地址,会对原变量的值传输影响。