1. 初识 JavaScript
JavaScript是一种流行的、功能齐全的脚本语言,主要用于网页开发。HTML构建结构,CSS美化外观,JavaScript增加动态交互,三者结合可以创建丰富、动态和交互式的Web页面。JavaScript可以操作网页的内容和样式,处理表单,以及创建复杂的Web应用程序。它是一种解释型语言,支持面向对象、命令式和函数式编程风格,可以在客户端(浏览器)和服务器端(如Node.js)运行。
2. JavaScript 运行过程
- 编写的代码是保存在文件中的, 也就是存储在硬盘(外存上).
- 双击 .html 文件浏览器(应用程序)就会读取文件, 把文件内容加载到内存中(数据流向: 硬盘 => 内存)
- 浏览器会解析用户编写的代码, 把代码翻译成二进制的, 能让计算机识别的指令(解释器的工作)
- 得到的二进制指令会被 CPU 加载并执行(数据流向: 内存 => CPU)
浏览器分成渲染引擎
+ JS
引擎
.
- 渲染引擎: 解析 html + CSS, 俗称 "内核"
- JS 引擎: 也就是 JS 解释器. 典型的就是 Chrome 中内置的 V8
JS
引擎逐行读取
JS
代码内容
,
然后解析成二进制指令
,
再执行
.
3. JavaScript 的组成
- ECMAScript(简称 ES): JavaScript 语法
- DOM: 页面文档对象模型, 对页面中的元素进行操作
- BOM: 浏览器对象模型, 对浏览器窗口进行操作
光有
JS
语法
,
只能写一些基础的逻辑流程
. 但是要想完成更复杂的任务,
完成和浏览器以及页面的交互
,
那么久需要
DOM API
和
BOM API.
4. JavaScript 的书写形式
1. 行内式
直接嵌入到
html
元素内部
<input type="button" value="点击" onclick="alert('hahah')">
注意
, JS
中字符串常量可以使用单引号表示
,
也可以使用双引号表示
. HTML 中推荐使用双引号
, JS
中推荐使用单引号
.
2. 内嵌式
写到
script
标签中
<script>
alert("hello")
</script>
3. 外部式
写到单独的
.js 文件中,hello.js 如下
alert("hello JavaScript")
<script src="hello.js"></script>
注意
,
这种情况下
script
标签中间不能写代码
.
必须空着
(
写了代码也不会执行
). 适合代码多的情况.
5. 语法介绍
注释
单行注释
// [
建议使用
]
多行注释
/* */
输入输出
输入
: prompt ,弹出一个输入框
prompt("请输入你的名字")
输出: alert ,弹出一个警示对话框
,
输出结果
输出: console.log ,在控制台打印一个日志
(
供程序员看
)
console.log("这是一条日志")
需要打开浏览器的开发者工具
(F12) => Console
标签页
才能看到结果
.
注意
:
在
VSCode
中直接输入
"log"
再按
tab
键
,
就可以快速输入
console.log
变量的使用
创建变量
(
变量定义
/
变量声明
/
变量初始化
)
var a = 10;
let b = 20
var 和 let 均
是
JS
中的关键字
,
表示这是一个变量,推荐使用 let,因为 let 是对 var 的完善版。
每个语句最后带有一个 ;
结尾,不过
JS
中可以省略
;
动态类型
1) JS 的变量类型是程序运行过程中才确定的(运行到 = 语句才会确定类型),随着程序运行, 变量的类型可能会发生改变.
let a = 1
console.log(typeof(a))
a = "hello"
console.log(typeof(a))
基本数据类型
JS
中内置的几种类型
- number: 数字,不区分整数和小数.
- boolean: true 真, false 假.
- string: 字符串类型.
- undefined: 只有唯一的值 undefined,表示未定义的值.
- null: 只有唯一的值 null,表示空值.
number 数字类型
JS
中不区分整数和浮点数
,
统一都使用
"
数字类型
"
来表示
.
let a = 10
let b = 1.1
console.log(typeof(a))
console.log(typeof(b))
特殊的数字值
- Infinity: 无穷大, 大于任何数字. 表示数字已经超过了 JS 能表示的范围.
- -Infinity: 负无穷大, 小于任何数字. 表示数字已经超过了 JS 能表示的范围.
- NaN: 表示当前的结果不是一个数字.
console.log(10/0)
console.log(-10/0)
console.log(10/"aaa")
string 字符串类型
基本规则
字符串字面值需要使用引号引起来
,
单引号双引号均可
.
let a = "haha";
let b = 'hehe';
let c = hehe; // 运行出错
如果字符串中本来已经包含引号咋办
?
let msg1 = "My name is "zhangsan""; // 出错
let msg2 = "My name is \"zhangsan\""; // 正确, 使用转义字符. \" 来表示字符串内部的引
号.
let msg3 = "My name is 'zhangsan'"; // 正确, 搭配使用单双引号
let msg4 = 'My name is "zhangsan"'; // 正确, 搭配使用单双引号
求长度
使用
string
的
length
属性即可
let a = "hahaha"
console.log(a.length)
字符串拼接
使用
+
进行拼接
let a = "my name is ";
let b = "zhangsan";
console.log(a + b);
注意
,
数字和字符串也可以进行拼接
let c = "my score is ";
let d = 100;
console.log(c + d);
注意
,
要认准相加的变量到底是字符串还是数字
console.log(100 + 100); // 200
console.log('100' + 100); // 100100
boolean 布尔类型
true表示
"
真" ,false表示 "假",boolean
参与运算时当做
1
和
0
来看待
.
undefined 未定义数据类型
如果一个变量没有被初始化过
,
结果就是
undefined,
是
undefined
类型
let a;
console.log(a);
undefined
和字符串进行相加
,
结果进行字符串拼接
console.log(a + "10"); // undefined10
null 空值类型
null 表示当前的变量是一个 "空值".
let a = null;
console.log(a + 10); // 10
console.log(a + "10"); // null10
注意
:
null
和
undefined
都表示取值非法的情况
,
但是侧重点不同
. null 表示当前的值为空
. (
相当于有一个空的盒子
) ,undefined 表示当前的变量未定义
. (
相当于连盒子都没有
)
运算符
JavaScript
中的运算符和
C/C++/Java
用法基本相同
.
此处不做详细介绍了
.需要注意的是以下运算符。
- == 比较相等(会进行隐式类型转换)
- !=
- === 比较相等(不会进行隐式类型转换)
- !==
if(1=="1")
console.log("==true")
else
console.log("==false")
if(1==="1")
console.log("===true")
else
console.log("===false")
数组
创建数组
使用
new
关键字创建
let arr = new Array(); // Array 的 A 要大写
使用字面量方式创建
[
常用
]
let arr = [];
let arr2 = [1, 2, 'haha', false]; // 数组中保存的内容称为 "元素"
注意
:
JS
的数组不要求元素是相同类型
.
这一点和
C, C++, Java
等静态类型的语言差别很大
.
但是
Python, PHP
等动态类型语言也是如此
.
获取数组元素
使用下标的方式访问数组元素
(
从
0
开始
)
let arr = ['小猪佩奇', '小猪乔治', '小羊苏西'];
console.log(arr);
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[2]);
arr[2] = '小猫凯迪';
console.log(arr);
如果下标超出范围读取元素
,
则结果为
undefined
console.log(arr[3]); // undefined
console.log(arr[-1]); // undefined
注意
:
不要给数组名直接赋值
,
此时数组中的所有元素都没了
.
新增数组元素
1.
通过修改
length
新增
相当于在末尾新增元素
.
新增的元素默认值为
undefined
2.
通过下标新增
如果下标超出范围赋值元素
,
则会给指定位置插入新元素
let arr = [];
arr[2] = 3;
console.log(arr);
此时这个数组的
[0]
和
[1]
都是
undefined
3.
使用
push
进行追加元素
let arr = [];
for (let i = 0; i < 5; i++)
arr.push(i);
console.log(arr);
删除数组中的元素
使用
splice
方法删除元素
let arr = [1, 2, 3, 4, 5];
// 第一个参数表示从下表为 1 的位置开始删除. 第二个参数表示要删除的元素个数是 2 个
arr.splice(1, 2);
console.log(arr);//1 4 5
函数
语法格式
// 创建函数/函数声明/函数定义
function 函数名(形参列表) {
函数体
return 返回值;
}
// 函数调用
函数名(实参列表) // 不考虑返回值
返回值 = 函数名(实参列表) // 考虑返回值
函数的定义和调用的先后顺序没有要求
. (
这一点和变量不同
,
变量必须先定义再使用
)
hello();
function hello()
{
console.log("hello");
}
关于参数个数
实参和形参之间的个数可以不匹配
.
但是实际开发一般要求形参和实参个数要匹配
1)
如果实参个数比形参个数多
,
则多出的参数不参与函数运算
sum(10, 20, 30); // 30
2)
如果实参个数比形参个数少
,
则此时多出来的形参值为
undefined
sum(10); // NaN, 相当于 num2 为 undefined.
函数表达式
另外一种函数的定义方式
let add = function () {
let sum = 0;
for (let i = 0; i < arguments.length; i++)
sum += arguments[i];
return sum;
}
console.log(add(10, 20));//30
console.log(add(1, 2, 3, 4,));//10
此时形如
function() { }
这样的写法定义了一个匿名函数
,
然后将这个匿名函数用一个变量来表示
.
后面就可以通过这个
add
变量来调用函数了
.
作用域
某个标识符名字在代码中的有效范围,
在 ES6
标准之前
,
作用域主要分成两个
- 全局作用域: 在整个 script 标签中, 或者单独的 js 文件中生效.
- 局部作用域/函数作用域: 在函数内部生效.
创建变量时如果不写
let ,
则得到一个全局变量
.
function test() {
num = 100;//未使用let声明,为全局变量
}
test();//注意需要先运行该函数,否则会报错找不到num
console.log(num);
// 执行结果100
作用域链
背景
:
- 函数可以定义在函数内部
- 内层函数可以访问外层函数的局部变量.
内部函数可以访问外部函数的变量
.
采取的是链式查找的方式
.
从内到外依次进行查找
.
let num = 1;
function test1() {
let num = 10;
function test2() {
console.log(num);
}
test2();
}
test1();// 执行结果10
执行
console.log(num)
的时候
,
会在
test2
的局部作用域中查找
num.
如果没找到
,
则继续去
test1
中查找.
如果还没找到
,
就去全局作用域查找
.
对象
1. 使用 字面量 创建对象 [常用]
- 使用 { } 创建对象
- 属性和方法使用键值对的形式来组织.
- 键值对之间使用 , 分割, 最后一个属性后面的 , 可有可无.
- 键和值之间使用 : 分割.
- 方法的值是一个匿名函数.
let a = {}; // 创建了一个空的对象
let student = {
name: '蔡徐坤',
height: 175,
weight: 170,
sayHello: function () {
console.log("hello");
}
};
使用对象的属性和方法
:
// 1. 使用 . 成员访问运算符来访问属性 `.` 可以理解成 "的"
console.log(student.name);
// 2. 使用 [ ] 访问属性, 此时属性需要加上引号
console.log(student['height']);
// 3. 调用方法, 别忘记加上 ()
student.sayHello();
2. 使用 new Object 创建对象
let student = new Object();
student.name = "蔡徐坤";
student.height = 175;
student['weight'] = 170;
student.sayHello = function () {
console.log("hello");
}
console.log(student.name);
console.log(student['weight']);
student.sayHello();
注意
,
使用
{ }
创建的对象也可以随时使用
student.name = "
蔡徐坤
"
;
这样的方式来新增属性
.
3. 使用 构造函数 创建对象
前面的创建对象方式只能创建一个对象
.
而使用构造函数可以很方便的创建多个对象
.
function 构造函数名(形参) {
this.属性 = 值;
this.方法 = function...
}
let obj = new 构造函数名(实参);
注意
:
- 在构造函数内部使用 this 关键字来表示当前正在构建的对象.
- 构造函数的函数名首字母一般是大写的.
- 构造函数不需要 return
- 创建对象的时候必须使用 new 关键字.
function Cat(name, type, sound) {
this.name = name;
this.type = type;
this.miao = function () {
console.log(sound); // 别忘了作用域的链式访问规则
}
}
let mimi = new Cat('咪咪', '中华田园喵', '喵');
let xiaohei = new Cat('小黑', '波斯喵', '猫呜');
let ciqiu = new Cat('刺球', '金渐层', '咕噜噜');
console.log(mimi);
mimi.miao();