1. 初始JavaScript
JavaScript简称JS
- 是一个世界上最流行的语言之一.
- 通过解释器运行的脚本(Script)语言
- 主要在客户端(浏览器)上运行.
脚本语言也叫做解释型语言,对于我们编写的代码,CPU无法直接处理,需要使用"转化器"把代码转换为计算机可以看懂的二进制,对于不同的语言在"转换"时的处理不同,导致二者的区别,
- 对于C/C++,Golang,汇编等,需要把源码全部转换为二进制指令,最终生成一个可执行程序,这种语言就是编译型语言,所使用的转换工具时编译器.
- 对于Python,JavaScript,PHP等语言,可以一边执行一边转换,并不会生成可执行程序,它们就是解释性语言,使用的转换工具就是解释器.
- 而对于Java,C#是半编译,半解释语言,源码需要先转化为一种中间文件(.class,即字节码文件),然后把该文件拿到虚拟机上运行.
1.1 应用场景:
- 服务器开发(node.js)
- Js最开始是运行在浏览器上,而浏览器中执行JS的模块叫做"JS引擎",后来谷歌创造了一个非常NB的JS引擎,V8 Woker,而node.js就是把V8 Woker进行封装后产品
- 服务端程序开发
- atom(代码编辑器)
- vscode(地表最强编辑器)
- 手机app开发
- React native, Week, uniapp
1.2 发展历史:
JavaScript 之父 布兰登 艾奇 (Brendan Eich) ,是大佬耗时10完成设计的🐮
曾经的布兰登
发明 JavaScript 之后的布兰登
JavaScript,CSS,html三者的关系
- HTML: 网页的结构(骨)
- CSS: 网页的表现(皮)
- JavaScript: 网页的行为(魂
1.3 运行过程:
打开一个页面时,浏览器会对从外存中读取文件,把内容加载到内存中,然后浏览器会将其转化成二进制指令,随后二进制指令会被CPU执行形成我们看见的页面.
浏览器分为渲染引擎和J引擎(逐行读取JS代码转化为二进制指令)
- 渲染引擎: 解析html+CSS,俗称"内核"
- JS引擎: JS解释器,例如Chrome的V8引擎
1.4 组成部分:
- ECMAScript(简称 ES): JavaScript 语法
- DOM: 页面文档对象模型, 对页面中的元素进行操作
- BOM: 浏览器对象模型, 对浏览器窗口进行操作
JS语法能够实现一些基础逻辑,要想实现用户和页面之间的交互功能,就需要使用DOM API和BOM API(主要针对浏览器的JS,如果是服务端则是node.js),这是因为浏览器把页面中的每个元素/标签都抽象成了一个对象,这时候就可以使用js来操作,继而操作页面内容
2. 基本知识
2.1 JavaScript的引入方式
和CSS相同具有3种不同方式
- 行内式
直接镶嵌到html元素内部:
<input type="button" value="点我" onclick="alert('hehe')">
alert()就是DOM提供的API,作用是弹出一个自定义内容的对话框
- 内嵌式
<script>
alert('haha')
</script>
- 外部式
<script src="hello.js"></script>
注:
- 在js中通常使用单引号代表字符串,
- 单行注释
//
,多行注释/**/
2.2 输入输出
- 输入
<script>
prompt('请输入你的年龄:')
</script>
- 输出
- alert弹出一个对话框
alert('Hello')
- console.log,在控制台打印一条日志
console.log('这是一条日志信息')
3. 语法基础
JavaScript和java有很多语法规则是相同的,但是有java的基础能够更快理解
3.1 变量
语法规则:
var 变量名 = 值
和Java,C/C++不同,var可以接受整型,浮点型,字符串,字符等等类型数据,它会对等号右边的数据自动进行类型推导.而在高版本的Java,C++,GO引入了这种方式:
//Java
var n = 10;
//C++
auto n = 10;
//Go
n := 10
示例:弹框提示用户并返回相关信息
var name = prompt('请输入姓名:')
var id = prompt('请输入学号:')
alert("欢迎回来: " + name + "学号: "+ id)
let和var相同,也可以表示一个变量类型.
在var未初始化时,其类型是undefined
动态类型
JS的变量是动态类型,而C/C++,Java是静态类型,变量类型在创建时就确定了,不会在运行时改变.
JS是解释性语言,是边解释边运行的,所以对于变量类型在运行是可以改变的,这种特性就是动态类型
示例:
var n = 'hello'
console.log(typeof(n))
n = 12
console.log(typeof(n))
注: typeof()
显示变量所属类型
那么动态语言好还是静态语言好呢?
对于静态语言编译器就可以做更严格的检查,对于动态语言表达能力更加强大,代码更加简洁,但是如果代码规模大了,就难以维护,成本增加,所以业界达成共识认为静态语言是更好的
3.2 基本数据类型
1) number
number: 数字,不区分整数和小数
示例:
var a = 07; // 八进制整数, 以 0 开头
var b = 0xa; // 十六进制整数, 以 0x 开头
var c = 0b10; // 二进制整数, 以 0b 开头
var d = 10 //十进制整数
var e = 10.12 //浮点数
特殊的数字值
- nfinity: 无穷大, 大于任何数字. 表示数字已经超过了 JS 能表示的范围.
- -Infinity: 负无穷大, 小于任何数字. 表示数字已经超过了 JS 能表示的范围.
- NaN: 表示当前的结果不是一个数字
var max = Number.MAX_VALUE
console.log(max * 2);
console.log(-max*2);
console.log('??'-10);
如果使用’??’ + 10是属于字符串拼接,得到的类型是字符串
2)string
使用规则: 可以使用’'或者""
var 变量名 = '数值'
var 变量名 = "数值"
字符串拼接:
和Java一样使用’+'实现
var str = 'hello'
var n = 10;
console.log(str + n);
字符串长度:
变量名.length
var str = 'hello'
var n = 10;
console.log((n+str).length);
3)boolean
表示语句的真假.
注: boolean在参与运算时被当作1和0,相当于把boolean隐式类型转换为number类型
console.log(true + 1);
console.log(false - 1);
对于一个编程语言,如果非常支持隐式类型转换,这被称为弱类型,否则时强类型,而类型的强弱和其是动态静态型语言成正交关系
对于C++是强类型语言还是弱类型语言是存在争议的.
- 这是因为C++的很多语法都是在严格控制类型,而C++为了兼容C不得不继承C中的部分隐式类型转换
4)undefined
代表未定义数据类型
如果一个变量没有被初始化过, 结果就是 undefined, 是 undefined 类型
var a;
console.log(a)
undefined 和字符串进行相加, 实际上是字符串拼接
console.log(a + "10"); // undefined10
undefined 和数字进行相加, 结果为 NaN
console.log(a + 10); // NaN
5)null
代表当前变量是一个"空值"
var b = null;
console.log(b + 10); // 10
console.log(b + "10"); // null10
注:
null 和 undefined 的区别:
- null 表示当前的值为空. (相当于有一个空的盒子),undefined 表示当前的变量未定义. (相当于连盒子都没有 )
官方bug
console.log(typeof(undefined));
console.log(typeof(null));
null应该是null类型,但是这里显示的是object,官方知道,但是没有改,因为该了会影响到目前JS代码的兼容性
6)Object
JS中没有类的概念,所以的对象都是object对象
3.3 运算符
JS中运算符和Java差不多,我们只说不同点
1) 算术运算符
+ - * / %
2)赋值运算符 & 复合赋值运算符
= += -= *= /= %=
3)自增自减运算符
a++ a-- --a ++a
4)比较运算符
> < >= <= == != === !===
这里的==
会默认隐式类型转换
console.log(10 == '10');
可以使用===
取消隐式类型转换
console.log(10 === '10');
5)逻辑运算符
&& || !
6)位运算符
& | ~ ^
7)移位运算符
<< >> >>>
3.4 条件语句
1) if语句
if (条件1) {
语句1
} else if (条件2) {
语句2
} else if .... {
语句...
} else {
语句N
}
2)三元表达式
条件 ? 表达式1 : 表达式2
条件为真, 返回表达式1 的值. 条件为假, 返回表达式2 的值
3)switch
switch (表达式) {
case 值1:
语句1;
break;
case 值2:
语句2:
break;
default:
语句N;
}
4)循环语句
while (条件) {
循环体;
}
执行过程:
- 先执行条件语句
- 条件为 true, 执行循环体代码.
- 条件为 false, 直接结束循环
5)for 循环
for (表达式1; 表达式2; 表达式3) {
循环体
}
执行过程:
- 先执行表达式1, 初始化循环变量
- 再执行表达式2, 判定循环条件
- 如果条件为 false, 结束循环
- 如果条件为 true, 则执行循环体代码.
- 执行表达式3 更新循环变量
3.5 数组
JS等动态语言的数组和Java等静态类型语言有很大不同
1)创建数组
使用关键字new 创建
var arr = new Array()
使用字面值创建
var arr = []
var arr1 = [1, "121", 13.31, false]
注: JS中数组内容可以是不同类型的元素
2)显示数组
- 输出整个数组
var arr = [1,'hello',false, null]
console.log(arr);
- 通过下标访问输出
var arr = [1,'hello',false, null]
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
3)获取元素
可以越界访问数组元素,得到的是undefined
var arr = [1,'hello',false, null]
console.log(arr[-10]);
console.log(arr[1000]);
console.log(arr[0]);
4)新增元素
- 通过push新增
在数组最后增加
var arr = [1,1,1]
var arr1 = []
for (var i = 0; i < arr.length; i++) {
arr1.push(arr[i])
}
console.log(arr1);
- 通过下标增加
超过数组下标增加,数组扩容,
var arr = [1,1,1]
arr[100] = '121'
console.log(arr);
小于数组下标增加,相当于增加一个Map,数组长度不变
var arr = [1,1,1]
arr[-1] = 'ha'
arr[-20] = 'hi'
console.log(arr);
5)删除元素
基本语法:
array.splice(index, howmany, item1, ....., itemX);
参数 | 描述 |
---|---|
index | 必需。整数,指定在什么位置添加/删除项目,使用负值指定从数组末尾开始的位置。 |
howmany | 可选。要删除的项目数。如果设置为 0,则不会删除任何项目 |
item1, …, itemX | 可选。要添加到数组中的新项目 |
如果只写前两个参数就是删除元素
var arr = [1,2,3,4,5,6,7,8]
console.log(arr);
arr.splice(2,2)
console.log(arr);
如果第二个参数是0,则是插入元素
var arr = [1,2,3,4,5,6,7,8]
console.log(arr);
arr.splice(2,0, 11,23,41)
console.log(arr);
如果都写了,则是替换+插入
var arr = [1,2,3,4,5,6,7,8]
console.log(arr);
arr.splice(2,1, 11,23,41)
console.log(arr);
3.6 函数
JS的函数和Java的函数有很大不同,下面是JS的语法格式
// 创建函数/函数声明/函数定义
function 函数名(形参列表) {
函数体
return 返回值;
}
// 函数调用
函数名(实参列表) // 不考虑返回值
返回值 = 函数名(实参列表) // 考虑返回值
JS使用
function
关键字声明一个函数,该函数没有返回类型和形参类型,因为它是动态类型语言,可以接受和返回任意类型数据,函数调用和Java一样的操作.
JS的函数可以先调用,后声明.
// 调用函数
hello();
// 定义函数
function hello() {
console.log("hello");
}
1)参数类型和个数
-
实参和形参的个数可以不同,
- 实参数>形参数: 多出的实参不参与运算
- 实参数<形参数: 少的形参默认为
undefined
function add(x, y) { return x + y; } console.log(add(10,20)); console.log(add(10,20,30)); console.log(add(10)); console.log(add('hello'));
2)函数表达式
函数内部存在一个内置变量,叫做argument
,是一个数组存放了所有的实参.
可以使用function() { }
定义一个匿名内部函数,用一个变量存放函数,接下来就可以调用函数.
var add = function() {
var sum = 0;
for(let i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum
}
console.log(add(10, 20));
console.log(add(1,2,3,4,5,6,7,8,9));
函数像普通变量一样,可以被赋值给变量,可以作为另一个函数的参数,可以作为另一个函数的返回值,所以称JS的函数为一等公民
3)作用域
在ES6标准前,作用域主要分为两个:
- 全局作用域: 作用于整个script标签或者单独的js文件
- 局部作用域/ 函数作用域: 在函数内部生效
// 全局变量
var num = 10;
console.log(num);
function test() {
// 局部变量
var num = 20;
console.log(num);
}
test();
console.log(num);
3.7 对象
JS与Java对对象概念上基本一致,但是具体的语法格式有所不同
1) 创建对象
- 使用字面量创建对象[常用]
// 创建一个空对象
var ikun = {}
var ikun = {
name: '蔡徐坤',
age: 24,
height: 175,
weight: 170,
sing: function() {
console.log("鸡你太美!");
},
jump: function () {
console.log("铁山靠");
},
rap: function() {
console.log("rap!");
}
}
注:
- 属性和方法都是通过键值对的方式创建
- 键值对之间用
,
分割- 键和值之间用
:
分割
使用属性和方法
// 1. 使用 . 成员访问运算符来访问属性 `.`
console.log(ikun.name);
// 2. 使用 [ ] 访问属性, 此时属性需要加上引号
console.log(ikun['height']);
// 3. 调用方法, 别忘记加上 ()
ikun.sing();
注: JS中的对象都是public,没有权限的
- 使用 new Object 创建对象
var student = new Object(); // 和创建数组类似
student.name = "蔡徐坤";
student.height = 175;
student['weight'] = 170;
student.sing = function () {
console.log("鸡你太美");
}
console.log(student.name);
console.log(student['weight']);
student.sing();
- 使用 构造函数 创建对象
基本语法:
function 构造函数名(形参) {
this.属性 = 值;
this.方法 = function...
}
var obj = new 构造函数名(实参);
使用构造函数重新创建学生对象
function Cat(name, id, gender) {
this.name = name;
this.id = id;
this.gender = function () {
console.log(name+age); // 别忘了作用域的链式访问规则
}
}
var S1 = new Cat('张三', '123', '男');
var S2 = new Cat('李四', '122', '男');
var S3 = new Cat('王五', '124', '男')
e.log(ikun[‘height’]);
// 3. 调用方法, 别忘记加上 ()
ikun.sing();
注: JS中的对象都是public,没有权限的
2. **使用 new Object 创建对象**
```js
var student = new Object(); // 和创建数组类似
student.name = "蔡徐坤";
student.height = 175;
student['weight'] = 170;
student.sing = function () {
console.log("鸡你太美");
}
console.log(student.name);
console.log(student['weight']);
student.sing();
- 使用 构造函数 创建对象
基本语法:
function 构造函数名(形参) {
this.属性 = 值;
this.方法 = function...
}
var obj = new 构造函数名(实参);
使用构造函数重新创建学生对象
function Cat(name, id, gender) {
this.name = name;
this.id = id;
this.gender = function () {
console.log(name+age); // 别忘了作用域的链式访问规则
}
}
var S1 = new Cat('张三', '123', '男');
var S2 = new Cat('李四', '122', '男');
var S3 = new Cat('王五', '124', '男')