1. 初识 JavaScript
1.1 JavaScript 是什么
1.JavaScript (简称 JS) 是世界上最流行的编程语言之一
2.是一个脚本语言, 通过解释器运行
3.主要在客户端(浏览器)上运行, 现在也可以基于 node.js 在服务器端运行
1.2 JavaScript 的能做的事情
1、网页开发(更复杂的特效和用户交互)
2、网页游戏开发
3、服务器开发(node.js)
4、桌面程序开发(Electron, VSCode 就是这么来的)
5、手机 app 开发
JavaScript 发展历史可以参考阮一峰大神的博客:http://www.ruanyifeng.com/blog/2011/06/birth_of_javascript.html
1.3 JavaScript 和 HTML 和 CSS 之间的关系
HTML: 网页的结构(骨) ;CSS: 网页的表现(皮); JavaScript: 网页的行为(魂)
1.4 JavaScript 运行过程
1、编写的代码是保存在文件中的, 也就是存储在硬盘(外存上).
2、双击 .html 文件浏览器(应用程序)就会读取文件, 把文件内容加载到内存中(数据流向: 硬盘 => 内存)
3、浏览器会解析用户编写的代码, 把代码翻译成二进制的, 能让计算机识别的指令(解释器的工作)
4、得到的二进制指令会被 CPU加载并执行(数据流向: 内存 => CPU)
运行逻辑如下所示:
浏览器分成渲染引擎 + JS 引擎.;
渲染引擎: 解析 html + CSS, 俗称 "内核"
JS 引擎: 也就是 JS 解释器. 典型的就是 Chrome 中内置的 V8 ;JS 引擎逐行读取 JS 代码内容, 然后解析成二进制指令, 再执行.
1.5 JavaScript 的组成
ECMAScript(简称 ES): JavaScript 语法
DOM: 页面文档对象模型, 对页面中的元素进行操作
BOM: 浏览器对象模型, 对浏览器窗口进行操作
重要概念: ECMAScript
这是一套 "标准", 无论是啥样的 JS 引擎都要遵守这个标准来实现.JavaScript 代码可以嵌入到 HTML 的 script 标签中.
1.5 JavaScript 的书写形式
1.5.1 行内式
直接嵌入到 html 元素内部
css
<input type="button" value="点击我一下" onclick="alert('已经点击')">
注意, JS 中字符串常量可以使用单引号表示, 也可以 使用双引号表示. HTML 中推荐使用双引号, JS 中推荐使用单引号
1.5.2. 内嵌式
写到 script 标签中
css
<script>
alert("haha");
</script>
1.5.3. 外部式
写到单独的 .js 文件中
html
<script src="hello.js"></script>
alert("hehe");
注意, 这种情况下 script 标签中间不能写代码. 必须空着(写了代码也不会执行).
1.6 输入输出
输入: prompt ,弹出一个输入框
html
// 弹出一个输入框
prompt("请输入您的姓名:");
输出: alert 弹出一个警示对话框, 输出结果
html
// 弹出一个输出框
alert("hello");
输出: console.log 在控制台打印一个日志(供程序员看)
html
// 向控制台输出日志
console.log("这是一条日志");
日志是程序员调试程序的重要手段 ,console 是一个 js 中的 "对象" . 表示取对象中的某个属性或者方法. 可以直观理解成 "的" console.log 就可以理解成: 使用 "控制台" 对象 "的" log 方法.
2. 语法概览
2.1 变量的使用
2.1.1 基本用法
1、创建变量(变量定义/变量声明/变量初始化)
html
var name = 'zhangsan';
var age = 20;
var 是 JS 中的关键字, 表示这是一个变量.
= 在 JS 中表示 "赋值", 相当于把数据放到内存的盒子中.
= 两侧建议有一个空格 每个语句最后带有一个 ; 结尾. JS 中可以省略 ; 但是建议还是加上. 注意, 此处的 ; 为英文分号.
JS 中所有的标点都是英文标点. 初始化的值如果是字符串, 那么就要使用单引号或者双引号引起来.
初始化的值如果是数字, 那么直接赋值即可.注意变量要先声明才能使用.
2.1.2 理解动态类型
、JS 的变量类型是程序运行过程中才确定的(运行到 = 语句才会确定类型)
、随着程序运行, 变量的类型可能会发生改变.
3)、C, C++, Java, Go 等语言是静态类型语言. 一个变量在创建的时候类型就确定了, 不能在运行时发生 改变.
2.1.3 基本数据类型
JS 中内置的几种类型
1、number: 数字. 不区分整数和小数.
2、boolean: true 真, false 假.
3、string: 字符串类型.
4、undefined: 只有唯一的值 undefined. 表示未定义的值.
5、null: 只有唯一的值 null. 表示空值.
1、number 数字类型
JS 中不区分整数和浮点数, 统一都使用 "数字类型" 来表示
html
var a = 07; // 八进制整数, 以 0 开头
var b = 0xa; // 十六进制整数, 以 0x 开头
var c = 0b10; // 二进制整数, 以 0b 开头
一个八进制数字对应三个二进制数字 ,一个十六进制数字对应四个二进制数字. (两个十六进制数字就是一个字节)
特殊的数字值:
Infinity: 无穷大, 大于任何数字. 表示数字已经超过了 JS 能表示的范围.
-Infinity: 负无穷大, 小于任何数字. 表示数字已经超过了 JS 能表示的范围.
NaN: 表示当前的结果不是一个数字.
cssvar max = Number.MAX_VALUE; // 得到 Infinity console.log(max * 2); // 得到 -Infinity console.log(-max * 2); // 得到 NaN console.log('hehe' - 10);
注意:
负无穷大 和 无穷小 不是一回事. 无穷小指无限趋近与 0, 值为 1 / Infinity
'hehe' + 10 得到的不是 NaN, 而是 'hehe10', 会把数字隐式转成字符串, 再进行字符串拼接.
可以使用 isNaN 函数判定是不是一个非数字.
cssconsole.log(isNaN(10)); // false console.log(isNaN('hehe' - 10)); // true
2、string 字符串类型
字符串字面值需要使用引号引起来, 单引号双引号均可.
3、boolean 布尔类型
表示 "真" 和 "假"
4、undefined 未定义数据类型
如果一个变量没有被初始化过, 结果就是 undefined, 是 undefined 类型
5、null 空值类型
null 表示当前的变量是一个 "空值".
css
var b = null;
console.log(b + 10); // 10
console.log(b + "10"); // null10
null 和 undefined 都表示取值非法的情况, 但是侧重点不同. null 表示当前的值为空. (相当于有一个空的盒子) ,undefined 表示当前的变量未定义. (相当于连盒子都没有)
2.2 运算符号
(略)
2.3 条件语句
2.3.1 if 语句
基本语法格式 条件表达式为 true, 则执行 if 的 { } 中的代码
2.3.2 三元表达式
是 if else 的简化写法,如下:
css
条件 ? 表达式1 : 表达式2
条件为真, 返回表达式1 的值. 条件为假, 返回表达式2 的值.
2.3.3 switch
更适合多分支的场景.
html
switch (表达式) {
case 值1:
语句1;
break;
case 值2:
语句2:
break;
default:
语句N;
}
2.4 循环语句
2.4.1 while 循环
html
while (条件) {
循环体;
}
执行过程:
1、先执行条件语句 条件为 true, 执行循环体代码.
2、条件为 false, 直接结束循环
2.4.2 continue
结束这次循环 吃五个李子, 发现第三个李子里有一只虫子, 于是扔掉这个, 继续吃下一个李子.
2.4.3 break
结束整个循环 ,吃五个李子, 发现第三个李子里有半个虫子, 于是剩下的也不吃了.
2.4.4 for 循环
javafor (表达式1; 表达式2; 表达式3) { 循环体 }
执行过程:
1、先执行表达式1, 初始化循环变量
2、再执行表达式2, 判定循环条件
3、如果条件为 false, 结束循环
4、如果条件为 true, 则执行循环体代码.
5、执行表达式3,更新循环变量
2.5 数组
2.5.1 创建数组
1、使用 new 关键字创建
java
// Array 的 A 要大写
var arr = new Array();
2、使用字面量方式创建 [常用]
java
var arr = [];
var arr2 = [1, 2, 'haha', false];
注意: JS 的数组不要求元素是相同类型. 这一点和 C, C++, Java 等静态类型的语言差别很大. 但是 Python, PHP 等动态类型语言也是如此.
2.5.2 获取数组元素
使用下标的方式访问数组元素(从 0 开始)
java
var arr = ['沈梦瑶', '袁一琦', '周湘'];
console.log(arr);
console.log(arr[0])
如果下标超出范围读取元素, 则结果为 undefined
注意: 不要给数组名直接赋值, 此时数组中的所有元素都没了.
2.5.3 新增数组元素
- 通过修改 length 新增
相当于在末尾新增元素. 新增的元素默认值为 undefined,代码如下:
java
var arr = [9, 5, 2, 7];
arr.length = 6;
console.log(arr);
console.log(arr[4], arr[5]);
- 通过下标新增
如果下标超出范围赋值元素, 则会给指定位置插入新元素
html
var arr = [];
arr[2] = 10;
console.log(arr)
//此时其他0,1位置的元素都是nudefined
- 使用 push 进行追加元素
代码示例: 给定一个数组, 把数组中的奇数放到一个 newArr 中.
html
var arr = [9, 5, 2, 7, 3, 6, 8];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] % 2 != 0) {
newArr.push(arr[i]);
}
}
2.5.4 删除数组中的元素
使用 splice 方法删除元素;
css
var arr = [9, 5, 2, 7];
// 第一个参数表示从下表为 2 的位置开始删除. 第二个参数表示要删除的元素个数是 1 个
arr.splice(2, 1);
console.log(arr);
// 结果
[9, 5, 7]
3. 函数
3.1 语法格式
javascript// 创建函数/函数声明/函数定义 function 函数名(形参列表) { 函数体 return 返回值; } // 函数调用 函数名(实参列表) // 不考虑返回值 返回值 = 函数名(实参列表) // 考虑返回值
1、函数定义并不会执行函数体内容, 必须要调用才会执行. 调用几次就会执行几次.
2、调用函数的时候进入函数内部执行, 函数结束时回到调用位置继续执行. 可以借助调试器来观察.
3、函数的定义和调用的先后顺序没有要求. (这一点和变量不同, 变量必须先定义再使用)
3.1.1 关于参数个数
实参和形参之间的个数可以不匹配. 但是实际开发一般要求形参和实参个数要匹配
-
如果实参个数比形参个数多, 则多出的参数不参与函数运算
-
如果实参个数比形参个数少, 则此时多出来的形参值为 undefined
3.1.2 函数表达式
另外一种函数的定义方式
javascript
var add = function() {
var sum = 0;
for (var 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
console.log(typeof add); // function
此时形如 function() { } 这样的写法定义了一个匿名函数, 然后将这个匿名函数用一个变量来表示. 后面就可以通过这个 add 变量来调用函数了. JS 中函数是一等公民, 可以用变量保存, 也可以作为其他函数的参数或者返回值.
3.2 作用域(全局变量与局部变量)
某个标识符名字在代码中的有效范围.
在 ES6 标准之前, 作用域主要分成两个 :
全局作用域: 在整个 script 标签中, 或者单独的 js 文件中生效.
局部作用域/函数作用域: 在函数内部生效.
1、创建变量时如果不写 var, 则得到一个全局变量.
javascriptfunction test() { num = 100; } test(); console.log(num); // 执行结果 100
3.2.1 作用域链
背景:
函数可以定义在函数内部
内层函数可以访问外层函数的局部变量.
内部函数可以访问外部函数的变量. 采取的是链式查找的方式. 从内到外依次进行查找.
javascriptvar num = 1; function test1() { var num = 10; function test2() { var num = 20; console.log(num); } test2(); } test1(); // 执行结果 20
执行 console.log(num) 的时候, 会现在 test2 的局部作用域中查找 num. 如果没找到, 则继续去 test1 中 查找. 如果还没找到, 就去全局作用域查找.运行逻辑如下:
4. 对象
4.1 基本概念
对象是指一个具体的事物.在 JS 中, 字符串, 数值, 数组, 函数都是对象. 每个对象中包含若干的属性和方法.
属性: 事物的特征.
方法: 事物的行为.
- 使用 字面量 创建对象 [常用]
使用 { } 创建对象
javascript
var s = {}; // 创建了一个空的对象
var student = {
name: '沈梦瑶',
height: 175,
weight: 170,
sayHello: function() {
console.log("hello");
}
};
使用 { } 创建对象
属性和方法使用键值对的形式来组织.
键值对之间使用 , 分割.
最后一个属性后面的 , 可有可无
键和值之间使用 : 分割. 方法的值是一个匿名函数.
使用对象的属性和方法:
javascript// 1. 使用 . 成员访问运算符来访问属性 `.` 可以理解成 "的" console.log(student.name); // 2. 使用 [ ] 访问属性, 此时属性需要加上引号 console.log(student['height']); // 3. 调用方法, 别忘记加上 () student.sayHello();
- 使用 new Object 创建对象
javascript
var 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();
- 使用 构造函数 创建对象
前面的创建对象方式只能创建一个对象. 而使用构造函数可以很方便 的创建 多个对象.
基本语法:
javascriptfunction 构造函数名(形参) { this.属性 = 值; this.方法 = function... } var obj = new 构造函数名(实参);
注意:
1、在构造函数内部使用 this 关键字来表示当前正在构建的对象.
2、构造函数的函数名首字母一般是大写的.
3、构造函数的函数名可以是名词.
4、构造函数不需要 return
5、创建对象的时候必须使用 new 关键字. this 相当于 "我"
使用构造函数重新创建猫咪对象:
javafunction Cat(name, type, sound) { this.name = name; this.type = type; this.miao = function () { console.log(sound); // 别忘了作用域的链式访问规则 } } var mimi = new Cat('咪咪', '中华田园喵', '喵'); var xiaohei = new Cat('小黑', '波斯喵', '猫呜'); var ciqiu = new Cat('刺球', '金渐层', '咕噜噜'); console.log(mimi); mimi.miao();
4.2 理解 new 关键字
new 的执行过程:
-
先在内存中创建一个空的对象 { }
-
this 指向刚才的空对象(将上一步的对象作为 this 的上下文)
-
执行构造函数的代码, 给对象创建属性和方法
-
返回这个对象 (构造函数本身不需要 return, 由 new 代劳了) 参考 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new
5. JavaScript 的对象和 Java 的对象的区别
- JavaScript 没有 "类" 的概念
对象其实就是 "属性" + "方法" .
类相当于把一些具有共性的对象的属性和方法单独提取了出来, 相当于一个 "模子" 在 JavaScript 中的 "构造函数" 也能起到类似的效果. 而且即使不是用构造函数, 也可以随时的通过 { } 的方式指定出一些对象 ;
- JavaScript 对象不区分 "属性" 和 "方法"
JavaScript 中的函数和普通的变量一样. 存储了函数的变量能够通过 ( ) 来进行调用执行.
- JavaScript 对象没有 private / public 等访问控制机制.
对象中的属性都可以被外界随意访问.
- JavaScript 对象没有 "继承"
继承本质就是 "让两个对象建立关联". 或者说是让一个对象能够重用另一个对象的属性/方法. JavaScript 中使用 "原型" 机制实现类似的效果.
例如: 创建一个 cat 对象和 dog 对象, 让这两个对象都能使用 animal 对象中的 eat 方法. 通过 proto 属性来建立这种关联关系 (proto 翻译作 "原型"),代码如下:
当eat方法被调用的时候,先在自己的方法列表中寻找, 如果找不到,就去找原型中的方法, 如果原型 中找不到, 就去原型的原型中去寻找...... 最后找到Object那里, 如果还找不到, 那就是未定义了。
ps:本次的内容就到这里了,如果对你有所帮助的话,就请一键三连哦!!!