文章目录
- 一、初识JavaScript
- 1.1JavaScript是什么?
- 1.2发展历史
- 1.3JavaScript和HTML和CSS之间的关系
- JavaScript的组成
- 二、前置知识
- 2.1第一个程序hello world
- 2.2JavaScript的书写形式
- 2.2.1行内式
- 2.2.2内嵌式
- 2.2.3外部式
- 2.3注释
- 2.4输入输出
- 2.4.1输入prompt
- 2.4.2输出alert
- 2.4.3输出console.log
- 三、语法概览
- 3.1变量的使用
- 3.1.1基本使用
- 3.1.2理解动态类型
- 3.2基本数据类型
- 3.2.1number数字类型
- 3.2.2String字符串类型
- 3.2.3boolean布尔类型
- 3.2.4undefined未定义数据类型
- 3.2.5null空值类型
- 3.3运算符
- 3.3.1算术运算符
- 3.3.2赋值运算符&复合赋值运算符
- 3.3.3自增自减运算符
- 3.3.4比较运算符
- 3.3.5逻辑运算符
- 3.3.6位运算
- 3.3.7移位运算
- 3.4条件语句
- 3.4.1if 语句
- 3.4.2三元表达式
- 3.4.3switch
- 3.5循环语句
- 3.5.1while 循环
- 3.5.2continue
- 3.5.3break
- 3.5.3for 循环
- 3.6数组
- 3.6.1创建数组
- 3.6.2获取数组元素
- 3.6.3新增数组元素
- 3.6.4删除元素
- 3.7函数
- 3.7.1语法格式
- 3.7.2函数表达式
- 3.7.3作用域
- 3.7.4作用域链
- 3.8对象
- 3.8.1基本概念
- 3.8.2理解new的概念
- 3.8.3JavaScript 的对象和 Java 的对象的区别
一、初识JavaScript
1.1JavaScript是什么?
JavaScript(简称js)这个语言是当下最流行的编程语言之一,
虽然js主要用于前端页面的开发,但是实际上,也可以进行服务器/客户端程序的开发。
当下,后端开发这里,可选择的语言有很多:java,c/c++,Go,Python,PHP,但是前端开发这里,JS就是一家独大。
JS也有一些挑战者:
1.Dart(google搞的下一代移动端开发平台上自带的编程语言)
2.Web Assembly类似“汇编语言”,在浏览器上定义了一组基础指令,可以通过一些第三方工具,把其他的主流编程语言给转换成WebAssembly,这时,C++,java,python…都可以通过这个途径来实现页面开发了。
3.TypeScript(目前最有希望的挑战者),TypeScript(简称TS)和JavaScript就类似C++和C,也就说TS完全支持JS当下的语法,并且也引入了一些新的语法规则,让你写的更爽。
JavaScript 的能做的事情:
网页开发(更复杂的特效和用户交互)
网页游戏开发
服务器开发(node.js)
桌面程序开发(Electron, VSCode 就是这么来的)
手机 app 开发
Java和JavaScript不能说一模一样,只能说毫无关系
1.2发展历史
1995 年, 用 10 天时间完成 JS 的设计 (由于设计时间太短,语言的一些细节考虑得不够严谨,导致
后来很长一段时间,Javascript 写出来的程序混乱不堪)
最初在网景公司, 命名为 LiveScript,
一般认为,当时 Netscape 之所以将 LiveScript 命名为 JavaScript,是因为 Java 是当时最流行的
编程语言,带有 “Java” 的名字有助于这门新生语言的传播。
其实 Java 和 JavaScript 之间的语法风格相去甚远
1.3JavaScript和HTML和CSS之间的关系
JS和前面讲的HTML、CSS类似,都是运行在浏览器上
在浏览器中,内置了一个JS的执行引擎(所谓的引擎,就对标了我们java的JVM)
JavaScript的组成
ECMAScript(简称 ES): JavaScript 语法
DOM API: 浏览器提供的一组,操作页面元素的API
BOM API: 浏览器提供的一组,操作浏览窗口的API
重要概念: ECMAScript
这是一套 “标准”, 无论是啥样的 JS 引擎都要遵守这个标准来实现.
啥叫标准? 车同轨, 书同文. 秦始皇最大的贡献之一, 就是制定了一套标准.
三流公司做产品, 一流公司做标准.
二、前置知识
2.1第一个程序hello world
运行在浏览器中的JS,是离不开html的,所以我们的通常是嵌入到html中进行编写的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//代码在这里写
</script>
</body>
</html>
我们的script标签里面可以放很多种编程语言,但是现在js就是默认的选项
我们这里写一个hello world看看网页效果
<script>
alert('hello world');//弹出一个警示对话框, 输出结果
//js里面语句不写分号";"也是可以的
//基于规范,我们这里写上
</script>
2.2JavaScript的书写形式
2.2.1行内式
把js写到html元素的内部
<button onclick="alert('hello')">我是一个按钮</button>
//在JS中,表示字符串单引号和双引号都可以
原先除了按钮啥也没有
你点击一下按钮会出现hello
2.2.2内嵌式
把js写到script标签中,也是我们这里讲的最常见的一种
2.2.3外部式
把js写到一个单独的.js文件中,在html里面通过script标签来引入
比如现在有一个app.js文件,里面有如下的代码
alert('hello app.js');
然后你在script标签中引用一下这个app.js文件
<script src="E:\java ee\app.js"></script>
下次你打开网页就会有这样的弹窗
实际开发中,外部式是用的最多的。它可以把js代码分成多个文件来分别表示。本篇文章还是以内嵌式为主,因为我们这里是刚刚入门,也不会写太复杂的代码,所以也不用把这些代码拆分开来。
2.3注释
js的注释
//
html
<!-- -->
css
/* */
2.4输入输出
2.4.1输入prompt
弹出一个输入框
prompt("请输入您的姓名:");
有点类似c语言的scanf,但是这种方法其实很少用得到,因为可以借助input标签来实现输入,或者一些点击按钮也可以
2.4.2输出alert
弹出一个警示对话框,输出结果
alert("hello");
2.4.3输出console.log
在控制台打印一个日志(供程序员查看)
console.log("这是一条日志");
这是我们开发中,最常用的一种输出方式。
alert弹框用户体验不好
console.log会把日志给输出到控制台中(这个控制台不是我们系统的黑框,而是浏览器自己的控制台,可以在开发者工具中看到)
比如我们这里写一个console.log
<script>
console.log("这是一条日志");
</script>
打开对应网页好像啥也没有
其实不是的,你打开开发者工具-控制台,会发现“这是一条日志”已经出现了
同时,js代码中如果出现语法错误,或者运行时出错,也会在控制台中显示
比如我们这里将第二个console拼写出错
<script>
console.log("这是一条日志");
consel.log('我也是一条日志')
</script>
然后控制台也会给你报错
三、语法概览
3.1变量的使用
3.1.1基本使用
创建变量(变量定义/变量声明/变量初始化)
var 变量名 =初始值
示例如下
var name = 'zhangsan';//创建一个名为name,字符串类型的变量
var age = 20;//创建一个名为age,数字类型的变量
var arr=[];//创建一个名为arr,数组类型的变量
不管你创建的是啥类型,都统一使用var这个关键字来表示,至于你变量具体是什么类型,这个取决于初始化的值是什么类型
var a=10;//给变量赋值
a=20;//修改变量
console.log(a)//读取变量内容
ps:为啥动漫中的角色都是要先喊出技能名字再真正释放技能?
就是因为变量要先声明才能使用
实战演练:
var name = prompt("请输入姓名:");
var age = prompt("请输入年龄:");
var score = prompt("请输入分数");
alert("您的姓名是: " + name + "\n" + "您的年龄是: " + age + "\n" + "您的分数是: " +
score + "\n");
//alert你也可以分三个写
// 表示字符串拼接, 也就是把两个字符串首尾相接变成一个字符串. \n 表示换行
3.1.2理解动态类型
这里var的类型也是可以运行过程中,中途随赋值修改的,这种行为就称为“动态类型”
var a=10;
a='hello';
console.log(a)
现在其实更倾向用let来替代var
var是旧版本(早期设计),有很多地方违背直觉,举个例子
比如这里的,我们把a放在大括号里,按道理出了大括号a就没有用了,
出了大括号再使用a应该是要报错的
<script>
{
var a=10;
}
console.log(a);
</script>
但这里控制台依旧打印出了a的值10
再来试试let
<script>
{
let a=10;
}
console.log(a);
</script>
用let创建一个a,a出了大括号,然后再用a就报错了
3.2基本数据类型
3.2.1number数字类型
数字进制表示
var a = 07; // 八进制整数, 以 0 开头
var b = 0xa; // 十六进制整数, 以 0x 开头
var c = 0b10; // 二进制整数, 以 0b 开头
特殊的数字值
Infinity: 无穷大, 大于任何数字. 表示数字已经超过了 JS 能表示的范围.
-Infinity: 负无穷大, 小于任何数字. 表示数字已经超过了 JS 能表示的范围.
NaN: 表示当前的结果不是一个数字
var max = Number.MAX_VALUE;
// 得到 Infinity
console.log(max * 2);
// 得到 -Infinity
console.log(-max * 2);
// 得到 NaN
console.log('hehe' - 10);
console.log('hehe' + 10);
//得到一个字符串hello10
3.2.2String字符串类型
基本规则:字符串字面值需要使用引号引起来, 单引号双引号均可
在JS中,表示字符串单引号和双引号都可以
var a = "haha";
var b = 'hehe';
var c = hehe; // 运行出错
如果字符串中本来已经包含引号咋办?
var msg = "My name is "zhangsan""; // 出错
var msg = "My name is \"zhangsan\""; // 正确, 使用转义字符. \" 来表示字符串内部的引号.
var msg = "My name is 'zhangsan'"; // 正确, 搭配使用单双引号
var msg = 'My name is "zhangsan"'; // 正确, 搭配使用单双引号
转义字符
有些字符不方便直接输入, 于是要通过一些特殊方式来表示.
\n
\\
\'
\"
\t
求长度
使用 String 的 length 属性即可
var a = 'hehe';
console.log(a.length);//4
var b = '哈哈';
console.log(b.length);//2
字符串拼接
使用 + 进行拼接
var a = "my name is ";
var b = "zhangsan";
console.log(a + b);
数字和字符串也可以进行拼接
var c = "my score is ";
var d = 100;
console.log(c + d);
注意, 要认准相加的变量到底是字符串还是数字
console.log(100 + 100); // 200
console.log('100' + 100); // 100100
3.2.3boolean布尔类型
表示 “真” 和 “假”
Boolean 参与运算时当做 1 和 0 来看待.
console.log(true + 1);//2
console.log(false + 1);//1
这样的操作其实是不科学的. 实际开发中不应该这么写.
3.2.4undefined未定义数据类型
如果一个变量没有被初始化过, 结果就是 undefined, 是 undefined 类型
var a;
console.log(a)
console.log(a+10)//undefined和数字相加结果为NaN
console.log(a+"10")
3.2.5null空值类型
null相当于这个值“没有值”
你打印的话也会打印一个null
let b=null;
console.log(b);
console.log(b+10);
console.log(b+"10");
3.3运算符
3.3.1算术运算符
+
-
*
/
%
js的/和大部分语言有些区别
x=1/2;
console.log(x);
大部分语言x=1/2应该是0,是区分整形和浮点型的,
但是js不区分,都是number类型
3.3.2赋值运算符&复合赋值运算符
=
+=
-=
*=
/=
%=
3.3.3自增自减运算符
++: 自增1
--: 自减1
3.3.4比较运算符
<
>
<=
>=
== 比较相等(会进行隐式类型转换)
!=
=== 比较相等(不会进行隐式类型转换)
!==
==和!=
只是比较两个变量的值,而不比较两个变量的类型,如果两个变量能够通过隐式类型转换,转换成相同的值,此时就认为也是相等的
===和 != =
既要比较变量的值,也要比较变量的类型,如果类型不相同,就直接认为不相等。
let a=10;
let b='10';
console.log(a==b);
console.log(a===b);
注:谈到比较两个对象,有三个维度的比较
1.比较身份(是不是同一个对象)
2.比较值(对象里存储的数据是否相同)
3.比较类型(两个对象是否是同一个类型)
java中==是比较身份
equals可以被重现,不重写也是默认比较身份,通过重写来设定成比较值
instanceof比较类型
js中==只是比较值
= = =同时比较值和类型
3.3.5逻辑运算符
用于计算多个 boolean 表达式的值.
&& 与: 一假则假
|| 或: 一真则真
! 非
java中&&和||很简单,就是返回一个true或false
js中&&和||返回的是其中的一个表达式
c=a||b
如果a的值为真(非0),此时c=a
如果a的值为假(0),此时c=b
c=0||0;
console.log(c)//a=0,则c=0
c=a&&b
如果a的值为假(0),此时c=a
如果a的值为真(非0),此时c=b
由于js与或非这种特性,我们常常会有如下写法的转换
写法1
let x=null;
if(!x){
x=0;
}
写法2
x=x||0
写法1和2的效果是一样的
c=a||b和c=a&&b这种写法也叫做短路求值
如果a这边已经能够确定表达式的值了,就不必再计算b了
3.3.6位运算
& 按位与
| 按位或
~ 按位取反
^ 按位异或
3.3.7移位运算
<< 左移
>> 有符号右移(算术右移)
>>> 无符号右移(逻辑右移)
3.4条件语句
3.4.1if 语句
基本语法格式
条件表达式为 true, 则执行 if 的 { } 中的代码
// 形式1
if (条件) {
语句
}
// 形式2
if (条件) {
语句1
} else {
语句2
}
// 形式3
if (条件1) {
语句1
} else if (条件2) {
语句2
} else if .... {
语句...
} else {
语句N
}
3.4.2三元表达式
是 if else 的简化写法.
条件 ? 表达式1 : 表达式2
3.4.3switch
更适合多分支的场景.
switch (表达式) {
case 值1:
语句1;
break;
case 值2:
语句2:
break;
default:
语句N;
}
3.5循环语句
重复执行某些语句
3.5.1while 循环
while (条件) {
循环体;
}
3.5.2continue
结束这次循环
吃五个李子, 发现第三个李子里有一只虫子, 于是扔掉这个, 继续吃下一个李子
var i = 1;
while (i <= 5) {
if (i == 3) {
i++;
continue;
}
console.log("我在吃第" + i + "个李子");
i++;
}
我在吃第1个李子
我在吃第2个李子
我在吃第4个李子
我在吃第5个李子
3.5.3break
结束整个循环
吃五个李子, 发现第三个李子里有半个虫子, 于是剩下的也不吃了.
var i = 1;
while (i <= 5) {
if (i == 3) {
break;
}
console.log("我在吃第" + i + "个李子");
i++;
}
我在吃第1个李子
我在吃第2个李子
3.5.3for 循环
for (表达式1; 表达式2; 表达式3) {
循环体
}
打印1-10
for (var num = 1; num <= 10; num++) {
console.log(num);
}
3.6数组
3.6.1创建数组
使用 new 关键字创建
// Array 的 A 要大写
var arr = new Array();
这种写法有点类似java的创建对象,用的比较少
使用字面量方式创建 [常用]
var arr = [];
var arr2 = [1, 2, 'haha', false];
// 数组中保存的内容称为 "元素"
//java中针对数组初始化用的是{}
//js使用[]
注意: JS 的数组不要求元素是相同类型.
3.6.2获取数组元素
使用下标的方式访问数组元素(从 0 开始)
var 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
3.6.3新增数组元素
- 通过修改 length 新增
var arr = [9, 5, 2, 7];
arr.length = 6;
console.log(arr);
console.log(arr[4], arr[5]);
- 通过下标新增
如果下标超出范围赋值元素, 则会给指定位置插入新元素
var arr = [];
arr[2] = 10;
console.log(arr)
3.使用 push 进行追加元素
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]);
}
}
console.log(newArr);
关于数组的一些其他知识点
3.6.4删除元素
使用 splice 方法删除元素
splice 这个方法,准确的来说是针对数组的某个片段进行替换
let arr=[1,2,3,4,5,6]
arr.splice(2,3)//从下标2开始,删除3个元素
console.log(arr)
let arr=[1,2,3,4,5,6]
arr.splice(2,3,100,200,300)//从下标2开始,替换3个元素
console.log(arr)
3.7函数
3.7.1语法格式
函数和java里面的方法一样的
// 创建函数/函数声明/函数定义
function 函数名(形参列表) {
函数体
return 返回值;
}
// 函数调用
函数名(实参列表) // 不考虑返回值
返回值 = 函数名(实参列表) // 考虑返回值
示例1:
function hello(){//既没有参数也没有返回值的函数
console.log('hello');
}
hello();//必须要调用一下函数才会有效果
示例2:
function add(x,y){//有参数也有返回值的函数
return x+y;
}
let result=add(1,2);//用result来接收add的返回值
let result2=add(1,'hello')
let result3=add('hello','world')
console.log(result);
console.log(result2);
console.log(result3);
3.7.2函数表达式
在js中,函数是“一等公民”,函数就像一个普通变量,可以被赋值给其他变量
也可以作为一个函数的参数,还可以作为一个函数的返回值。
(函数和普通变量没有本质区别,但是函数这样的变量相比于普通变量多了个功能:可调用)
function hello(){
console.log('hello');
}
let f=hello;//hello后面没有接(),说明不是函数调用,这里是函数赋值
f();
上面代码的另一种写法
let f=function hello(){
console.log('hello');
}
f();
此时形如 function() { } 这样的写法定义了一个匿名函数, 然后将这个匿名函数用一个变量来表示.
后面就可以通过这个 add 变量来调用函数了
如果还要简化,你可以把hello给省略,反正后面你都用f了,hello这名字也没啥用
let f=function (){
console.log('hello');
}
f();
ps:这种没有名字的函数,也称匿名函数,也称lambda表达式
3.7.3作用域
某个标识符名字在代码中的有效范围.
在 ES6(js的一个版本) 标准之前, 作用域主要分成两个
1.全局作用域: 在整个 script 标签中, 或者单独的 js 文件中生效.
2.局部作用域/函数作用域: 在函数内部生效
// 全局变量
var num = 10;
{
console.log(num);//10
}
function test() {
// 局部变量
var num = 20;
console.log(num);
}
function test2() {
// 局部变量
var num = 30;
console.log(num);
}
test();//20
test2();//30
console.log(num);//10
在ES6之后,引入了let,也就有了块级作用域,一个变量在{}内部定义,是无法被{}访问的
在js里面,{ }内部的代码,可以访问{ }外的代码
3.7.4作用域链
3.8对象
3.8.1基本概念
对象是指一个具体的事物.
“电脑” 不是对象, 而是一个泛指的类别. 而 “我的联想笔记本” 就是一个对象.
在 JS 中, 字符串, 数值, 数组, 函数都是对象.
每个对象中包含若干的属性和方法.
属性: 事物的特征.
方法: 事物的行为.
例如, 你有一个女票.
她的身高体重三围这些都是属性.
她的唱歌, 跳舞都是方法
创建对象的3种方法
1.使用 { } 创建对象
let People={
name:'孙笑川',
age:20,
height:170,
weight:170,
sing:function(){
console.log("那你去找物管啊,你再骂!")
}
}
console.log(People.name);
console.log(People.age);
People.sing();
每个属性和方法,其实都是通过“键值对”这样的方法来表达的,{}表示这是个对象。
键值对之间,使用,分割。
键和值之间,使用:分割。
2.使用 new Object 创建对象
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();
注意, 使用 { } 创建的对象也可以随时使用 student.name = “蔡徐坤”; 这样的方式来新增属性
3. 使用 构造函数 创建对象
前面的创建对象方式只能创建一个对象. 而使用构造函数可以很方便 的创建 多个对象.
例如: 创建几个猫咪对象
var mimi = {
name: "咪咪",
type: "中华田园喵",
miao: function () {
console.log("喵");
}
};
var xiaohei = {
name: "小黑",
type: "波斯喵",
miao: function () {
console.log("猫呜");
}
}
var ciqiu = {
name: "刺球",
type: "金渐层",
miao: function () {
console.log("咕噜噜");
}
}
此时写起来就比较麻烦. 使用构造函数可以把相同的属性和方法的创建提取出来, 简化开发过程
基本语法:
function 构造函数名(形参) {
this.属性 = 值;
this.方法 = function...
}
var obj = new 构造函数名(实参);
我们最常见的写法还是第一种写法
3.8.2理解new的概念
new 的执行过程:
- 先在内存中创建一个空的对象 { }
- this 指向刚才的空对象(将上一步的对象作为 this 的上下文)
- 执行构造函数的代码, 给对象创建属性和方法
- 返回这个对象 (构造函数本身不需要 return, 由 new 代劳了)
参考 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new
3.8.3JavaScript 的对象和 Java 的对象的区别
JS虽然有对象,但是JS并不算是一个面向对象编程的语言
JS里面没有封装,继承,多态这些面向对象的这些特性。
ps:JS中没有原生提供“继承”这种机制的,但是JS里有一个曲线救国的方法,“原型”,基于原型机制,可以模拟实现一个类似于继承的效果(把一个对象的所有属性,给自动的加入到一个新的对象中…)