1.概述
1.相关概念
js:运行在客户端的脚本语言。
脚本语言:解释性语言,不需要编译,运行过程中直接由js解释器(js引擎)逐行来进行解释执行。
浏览器执行js的过程: 浏览器分为两个部分:渲染引擎+js引擎
- 渲染引擎:解析HTML和CSS,俗称内核,如Chrome的blink
- js引擎:又称js解释器。用来读取网页中的js代码,对其处理后运行,比如Chrome的V8
浏览器通过内置的js解释器来执行js代码。js引擎执行代码时逐行解释每一句源码(转换为机器语言),然后交由计算机执行。
js组成:
- ECMAscript:js语法
- DOM:页面文档对象模型
- BOM:浏览器对象模型
ECMAScript: 是一种由Ecma国际(前身为欧洲计算机制造商协会,European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScript(网景公司)或JScript(微软公司),所以它可以理解为是JavaScript的一个标准,但实际上后两者是ECMA-262标准的实现和扩展。
DOM: 文档对象模型,是 HTML 和 XML 文档的编程接口。
- HTML DOM 定义了访问和操作 HTML 文档的标准方法。
- DOM 以树结构表达 HTML 文档。
BOM: 浏览器对象模型,浏览器对象模型提供了独立与内容的、可以与浏览器窗口进行互动的对象结构,BOM由多个对象构成,其中代表浏览器窗口的window对象是BOM的顶层对象,其他对象都是该对象的子对象。
标识符: 开发人员为变量、属性、函数、参数取的名字。标识符不能是关键字或保留字。
关键字: js本身已经使用了的字。
保留字: 预留的关键字。
2.书写位置
js有三种书写位置:行内、内嵌、外部。
<body>
<!--行内式的js,直接写到元素的内部-->
<input type="button" value="按钮" onclick="alert('我被行内式点了')">
</body>
<head>
<meta charset="UTF-8">
<title>js1</title>
<!--内嵌式的js-->
<script>
alert('内嵌式弹窗');
</script>
</head>
my.js:
alert('外部式弹窗');
html:
<script src="my.js"></script>
小结:
- 可以将单行或少量js代码写在HTML标签的事件属性中(以
on开头的属性,如onclick) - 在HTML中推荐使用 "",在js中推荐使用 ''
- 行内式可读性差,引号易错
2.输入输出语句
alert(msg) 浏览器弹出警示框
sonsole.log(msg) 浏览器控制台打印输出信息(F12)
prompt(info) 浏览器弹出输入框,用户可以输入
2.变量
变量:内存中开辟的存储数据的空间,数据可修改。可以通过变量名找到内存中的数据。
1.声明变量
var
var age;
age = 3;
var name = 'zhangsan';
var a = a,
b = b,
c = c;
使用没被赋值的变量——undefined
不声明,直接使用——不建议
重复声明同一变量并赋值——覆盖
<script>
var name = prompt('输入名字')
alert(name);
</script>
交换两个变量的值:
var temp = 0;
var a1 = 1;
var a2 = 2;
temp = a1;
a1 = a2;
a2 = temp;
console.log(a1,a2);
2.数据类型
1.简单数据类型
不同数据的存储空间不同,为节省空间所以要分类。
- js是一种弱类型(动态语言),即不用提前声明变量类型,在运行过程中,类型会被自动确定。
- 运行时,js引擎根据 = 右边变量值来确认数据类型。
- js是动态类型,意味着同一变量可作不同的类型。
简单数据类型:
| 简单数据类型 | 说明 | 默认值 |
|---|---|---|
| Number | 数字型,包含 整型 浮点型 | 0 |
| Boolean | 布尔型 | false |
| String | 字符串 | "" |
| Undefined | 只声明不赋值 | undefined |
| Null | 空值 | null |
/*
/*
数字型——Number
Infinity——无穷大(越界)
-Infinity——无穷小(越界)
NaN——非数字
isNaN——判断是否是Number,是返回true,否返回false
*/
var num = 1;
var PI = 3.14;
var num1 = 0o11;//八进制 9
var num2 = 0x11;//八进制 17
var max = Number.MAX_VALUE;//1.7976931348623157e+308
var min = Number.MIN_VALUE;//5e-324
console.log(isNaN(max));
/*
字符串——String
js可以单引号嵌双引号或者双引号嵌单引号
*/
var str1 = "我是\n'张三'呀";
var str2 = '"张三"是我呀';
var len = str1.length;//获取长度
var str3 = str1 + str2;//字符串拼接,拼接都会转为String
console.log(str1 + ' 有' + len + '个字符');
/*
布尔型——Boolean
*/
var flag = true;
var num3 = flag + 1;//2
/*
未定义——Undefined
*/
var und;
console.log(und);
/*
非数字——NaN
*/
console.log(und + 1);
/*
空值——Null
*/
console.log(null + 1);
console.log(null + '1');
console.log(typeof und);
字符串转义字符: 转义字符得写到引号中
| 转义符 | 说明 |
|---|---|
| \n | 换行,newLine |
| \\ | 斜杠\ |
| \' | 单引号 |
| \" | 双引号 |
| \t | tab缩进 |
| \b | 空格blank |
获取数据类型——typeOf
prompt获取到的值是字符型的
字面量: 源代码中一个固定值的表示法,通俗来说就是字面量表示如何表达这个值。
2数据类型的转换
把一种数据类型转换为另一种数据类型。
转换为字符串类型:
| 方法 | 说明 |
|---|---|
| toString() | 转换为字符串 |
| String()强制转换 | 转换成字符串 |
| + | 拼接隐式转换 |
var num = 1;
var str = num.toString();
var str1 = String(num);
var str2 = num + '';
转换为数字类型:
| 方法 | 说明 |
|---|---|
| parseInt(String) | 将String转换为Number |
| parseFloat(String) | 将String转换为Number |
| Number()强制转换 | |
| - * / | 算术符隐式转换 |
转换为布尔型:
| 方法 | 说明 |
|---|---|
| Boolean()强转 |
/*
* 空值、否定的值会被转换为false,如:''、0、NaN、null、undefined
* 其余值转换为true
* */
console.log(Boolean(NaN));
3.运算符
运算符优先级:
| 优先级 | 运算符 | 顺序 |
|---|---|---|
| 1 | 小括号 | () |
| 2 | 一元运算符 | ++ -- ! |
| 3 | 算术运算符 | 先 * / 后 + - |
| 4 | 关系运算符 | > >= < <= |
| 5 | 相等运算符 | == != === !== |
| 6 | 逻辑运算符 | 先&& 后|| |
| 7 | 赋值运算符 | = |
| 8 | 逗号运算符 | , |
注意——
==和===的区别: == 代表相同, ===代表严格相同
==如果两个值类型相同,再进行三个等号(===)的比较
如果两个值类型不同,也有可能相等,需根据以下规则进行类型转换在比较:
- 如果一个是null,一个是undefined,那么相等
- 如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较
===
- 如果类型不同,就一定不相等
- 如果两个都是数值,并且是同一个值,那么相等;如果其中至少一个是NaN,那么不相等。(判断一个值是否是NaN,只能使用isNaN( ) 来判断)
- 如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等。
- 如果两个值都是true,或是false,那么相等
- 如果两个值都引用同一个对象或是函数,那么相等,否则不相等
- 如果两个值都是null,或是undefined,那么相等
4.if、switch、for、while
1.if
var age = prompt('输入年龄') - 0;
if (age >= 18){
alert("已成年");
}else {
alert('未成年');
}
2.三元表达式
var num = 17;
console.log(num % 10 == 7 ? '对' : '不对');
3.switch
switch (prompt('输入你的姓氏')) {
case '陈':
alert('你姓陈');
break;
case '刘':
alert('你姓刘');
break;
case '吕':
alert('你姓吕');
break;
case '董':
alert('你姓董');
break;
default:
alert('你姓宋');
}
4.for
for (var i = 0; i < 100; i++) {
console.log(i);
}
打印金字塔⭐
var str = '';
for (var i = 1, j = 5; i <= 5; i++,j--) {
var m = j, n = i;
while (m >= 0){
str += ' ';
m--;
}
while (n > 0){
str += '⭐';
n --;
}
str += '\n';
}
console.log(str)
5.while
var i = 100;
while (i > 1){
console.log(i);
i -= 10;
}
6.continue和break
continue 跳出本次循环
break 跳出一层循环
var i = 100;
OUT:
for (var j = 0; j < 100; j++) {
for (var k = 0; k < 100; k++) {
if (i - 10 == 0) break OUT;
console.log(i);
i--;
}
}
5.数组
一组数据的集合。
创建数组:
var a = []; //空数组
a[0]=1;
a[1]="hello";
//数组下标不仅仅可以是数字,也可以为文本字符串,那么此时数组就是一个关联数组
a["姓名"]="张三";
a["年龄"]=23;
var a = [1, 2, 3]; //包含具体元素的数组
var a = new Array(); //空数组
var a = new Array(1,2,3);//数值
var a = new Array(3);//长度
修改数组长度:
var a = new Array(1,2,3);//数值
a.length = 5;
console.log(a);
检测是否为数组:
/*
instanceof运算符
*/
var arr = [];
console.log(arr instanceof Array);
/*
Array.isArray()
*/
console.log(Array.isArray(arr));
往数组中增删元素:
/*
push: 末尾追加元素,返回值为新数组长度
*/
var arr = [1,2,3,4];
arr.push(8,7,6);
/*
unshift: 开头添加元素,返回值为新数组的长度
*/
arr.unshift(9,4);
/*
pop: 删除数组最后一个元素,并返回删除的元素
*/
arr.pop();
/*
shift: 删除数组第一个元素,并返回删除的元素
*/
arr.shift();
reverse、sort、indexOf、lastIndexOf、toString、join
6.函数
将重复使用的代码封装成函数。
function f() {
console.log('f');
return undefined;
}
f();
function add(num) {
var sum = 0;
while (num > 0){
sum += num;
num--;
}
return sum;
}
var sum = add(100);
var add = function(num) {
var sum = 0;
while (num > 0){
sum += num;
num--;
}
return sum;
}
console.log(add(100))
函数形参与实参个数不匹配的问题:
- 实参个数 > 形参个数 —— 取到形参的个数,多余的实参无效
- 实参个数 < 形参个数 —— 多余的形参接收不到值,为undefined
函数的返回值: 如果需要返回值,就返回;如果不需要返回值,仍然建议返回一个undefined。
arguments 是当前函数的一个内置对象,所有函数都有一个arguments对象,其中存储了传递的所有实参(数组形式)。
可以获取并修改对应的形参值。
function func1(a, b, c) {
console.log(arguments[0]);
// expected output: 1
console.log(arguments[1]);
// expected output: 2
console.log(arguments[2]);
// expected output: 3
}
func1(1, 2, 3);
JavaScript的作用域: 代码名在某个范围内起作用和效果,目的是为了提高程序的可靠性且减少命名冲突。
js的作用域(es6)之前: 全局作用域、局部作用域
- 全局:整个script标签、一个单独的js文件
- 局部:在函数内部
js在es6时才新增的块级作用域。
7.预解析
js代码是由浏览器的js解析器来执行的。js解析器运行js代码的时候分为两步:预解析、代码执行。
- 预解析:js引擎将js里面的所有var还有function提升到当前作用域的最前面
- 代码执行:执行代码书写的顺序,从上往下执行
预解析: 分为 变量与解析(函数提升) 和 函数与解析(变量提升)。
- 变量提升:把所有的变量声明提升到当前的作用域最前面,不提升赋值操作
- 函数提升:把所有的函数声明提升到当前作用域的最前面,不调用函数
8.对象
对象是一个具体的事物。
在js中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
对象由属性和方法组成的。
- 属性:事务的特征(如一个人的发色)
- 方法:事务的行为(如学习)
相比于变量和数组,对象的表达结构更清晰、更强大。
创建对象的三种方式:
- 字面量
- new Object
- 构造函数
/*
通过Object()方法来创建
*/
var obj2 = new Object();
/*
通过字面量法创建对象
*/
var obj = {};//空对象
obj.name = 'zhangsan';
obj.behave = function(){
console.log('无所事事');
}
var obj1 = {
oname: '张三',
age: 18,
sex: '男',
behave: function () {
console.log('法律讲坛');
}
}
console.log(obj1.oname);
console.log(obj1['age']);
obj1.behave();
/*
通过构造函数创建对象
提高代码复用性,减少重复代码
函数中封装的是对象(类似Java的类)
*/
function Animal(uname,species) {
this.uname = uname;
this.species = species;
this.roar = function (call) {
console.log(uname + ': ' + call);
}
}
var cat = new Animal('胖橘','cat');
cat.roar('meow');
console.log(typeof cat);
new 的执行过程:
- new 构造函数 在内存中创建了一个空的对象
- this 会指向这个空的对象
- 执行构造函数中的代码,给空对象添加属性和方法
- 返回这个对象
for in遍历对象: 将属性和方法一起遍历。
for (const catKey in cat) {
console.log(catKey);//catKey变量 输出 属性名
console.log(cat[catKey]);//得到属性值,arguments内置对象
}
9.内置对象
js中的对象分为3种:自定义对象、内置对象、浏览器对象。
前面两种对象是js基础内容,属于ECMAScript,第三个属于js独有的。
内置对象就是js自带的一些对象,这些对象供开发者调用,并提供了一些常用的或最基本而必要的功能(属性和方法)。
MDN: developer.mozilla.org/zh-CN/
W3C: www.w3school.com.cn/
自定义数学对象:
var myMath = {
max: function(){
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max){
max = arguments[i];
}
}
return max;
}
}
console.log(myMath.max(1,5,98,75));
获取当前距离1970年1月1日00:00的毫秒数(时间戳):
var date = new Date();
/*
方法一
*/
console.log(date.valueOf());
/*
方法二
*/
console.log(date.getTime());
/*
方法三
*/
console.log(+new Date());
/*
方法四
*/
console.log(Date.now());
倒计时:
function countDown(time) {
var nowTime = +new Date();//时间戳
var inputTime = +new Date(time) ;//输入时间的时间戳
var times = (inputTime - nowTime) / 1000;//差值
var d = parseInt(times / 60 / 60 /24);//天
d = d < 10 ? '0' + d : d;
var h = parseInt(times / 60 / 60 % 24);//时
h = h < 10 ? '0' + h : h;
var m = parseInt(times / 60 % 60)//分
m = m < 10 ? '0' + m : m;
var s = parseInt(times % 60);
return d + '天' + h + '时' + m + '分' + s + '秒';
}
console.log(countDown('2022-6-3 11:0:00'));
var date = new Date();
console.log(date);
10字符串对象
基本包装类型: 将简单数据类型包装为复杂数据类型,这样基本数据类型就有了属性和方法。
包装步骤:
var str = 'Tom';
1.将简单数据类型包装为复杂数据类型
var temp = new String('Tom');
2.把临时变量的值给 str
str = temp;
3.销毁临时变量
temp = null;
字符串不可变: 字符串中的值不可变,如果重复给一个字符串变量赋值,会不断在内存中开辟空间来存储新值,然后让字符串变量指向新值。
indexOf(value) 获取字符在字符串中的位置
charAt(index) 获取指定位置的字符
charCodeAt(index) 获取指定位置的字符的ascll码
str[index] 获取指定位置处的值
统计字符串中每个字符出现的次数:
var strs = 'jcsdibvdsovsjnjk';
function getNums(strs){
var nums = {};
for (var i = 0; i < strs.length; i++){
var str = strs.charAt(i);
if (nums[str]){
nums[str]++;
}else {
nums[str] = 1;
}
}
console.log(nums);
}
getNums(strs);
获取出现次数最多的字符:
var strs = 'jcsdibvdsovsjnjk';
function getNums(strs){
var nums = {};
for (var i = 0; i < strs.length; i++){
var str = strs.charAt(i);
if (nums[str]){
nums[str]++;
}else {
nums[str] = 1;
}
}
console.log(nums);
//遍历对象
var max = 0;
var target;
for (var k in nums){
if (nums[k] > max){
max = nums[k];
target = k;
}
}
console.log('出现次数最多字符的是 ' + target + ',出现了' + max + '次');
}
getNums(strs);
concat(str1,str2,...) 等效于+
substr(start,end) 截取子串
replace(oldStr,newStr) 替换字符串
split(‘*’) 分隔符
toUpperCase() 全转换为大写
toLowerCase() 全转换为小写
11数据类型内存分配
js分为两种数据类型:简单数据类型(值类型)、复杂数据类型(引用类型)
- 值类型:在存储时变量中存储的是值本身
String、Number、Boolean、undefined、null(返回的是一个空对象) - 引用类型:用
new创建的对象(自定义对象、系统对象)
Object、Array、Date
堆和栈:
- 堆(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等
存放简单数据类型 - 栈(操作系统):由程序员分配释放,如果不释放,则由垃圾回收机制回收
存储复杂数据类型