【Java成王之路】EE初阶第二十篇: 前端三剑客 JavaScript 基础语法篇

目录

初识JavaScript

什么是JavaScript

Java 和 JS 的区别

JavaScript 的基本构成

JavaScript的书写形式 

JS的引入形式

上面介绍的是内嵌式,除此之外还有其他的方式.

行内式,把JS写到HTML元素中

外部式

把JS代码写到一个单独的文件中,由html来引入.

输入输出(

输入(基本用不到,简单一说): prompt

输出: alert

输出: console.log

 JavaScript的基本语法

变量的创建

​编辑

修改变量

动态类型

 typeof查看变量类型

基本数据类型

number 数字类型

 数字进制表示

特殊的数字值

 string 字符串类型

求长度

boolean 布尔类型

undefined 未定义数据类型

 运算符

算术运算符

赋值运算符 & 复合赋值运算符

自增自减运算符

比较运算符

逻辑运算符

位运算

移位运算

条件语句

三元表达式

switch

循环语句

while 循环

continue

break

for 循环

小结:

数组 

创建数组的方式

 下标越界

使用 push 进行追加元素

​编辑

删除数组中的元素 

函数

函数语法格式

参数个数

函数表达式 

作用域 

作用域链 

 对象

对象的创建

1. 使用 字面量 创建对象 [常用]

2. 使用 new Object 创建对象


初识JavaScript

什么是JavaScript

JavaScript (简称 JS)

是世界上最流行的编程语言之一

是一个脚本语言, 通过解释器运行

主要在客户端(浏览器)上运行, 现在也可以基于 node.js 在服务器端运行.

JavaScript 最初只是为了完成简单的表单验证(验证数据合法性), 结果后来不小心就火了.

当前 JavaScript 已经成为了一个通用的编程语言

JavaScript 的能做的事情:

网页开发(更复杂的特效和用户交互)

网页游戏开发

服务器开发(node.js)

桌面程序开发(Electron, VSCode 就是这么来的)

手机 app 开发

Java 和 JS 的区别

Java是运行在JCM里的

JS通常是运行 在浏览器 中的.

像 Chorme 内置的 JS 引擎叫做 V8 Worker.

V8引擎也被人单独的提取出来,可以嵌入到其他的程序中(谁的程序嵌入了V8,谁就能执行JS了)

nodeJS这个程序就是嵌入了V8,同时又给JS封装提供了一组相关的api,这也就让JS也具备了开发服务程序/桌面应用程序的能力.

Java的运行,主要是靠JVM,JVM把.class文件(二进制字节码)加载到内存中,然后解释执行,然后把这些java的字节码转成CPU指令.

JS的运行,是浏览器要先加载HTML,HTML中通过一些方式引入JS(JS的代码大概率是通过网络的方式被下载到浏览器中)然后浏览器再调用V8引擎来解释执行JS的代码.也是由V8引擎把JS翻译成2进制的机器指令,然后运行.

JavaScript 的基本构成

 

 如果是跑在非浏览器环境下的 JS (nodejs),没有 DOM 和 BOM.

会有其他的一组api

JavaScript的书写形式 

第一个程序

 效果

 JS可以通过 script 标签,嵌入到html中.

script 标签,可以嵌入很多种语言,不仅仅是JS.

因为时间原因,其他的语言都已经淹没在历史长河中了.

JS的引入形式

上面介绍的是内嵌式,除此之外还有其他的方式.

行内式,把JS写到HTML元素中

举例:

创建一个按钮

效果

但是此时点网页上的这个按钮没有任何反应

 现在加上红框里的内容之后

点击按钮之后就会弹出一个窗口

 注意: JS中的字符串可以使用双引号,也可以使用单引号.(JS不区分字符串和字符)

           双引号和单引号可以搭配使用.

           外面是双引号,里面就可以使用单引号

           外面是单引号,里面就可以使用双引号

外部式

把JS代码写到一个单独的文件中,由html来引入.

举例

创建一个js文件,添加内容

 然后通过这样一个代码就能够把js文件引入到html中

 这个操作往往就会触发一个网络请求.浏览器就会根据当前src对应的路径来从服务器获取dome10.js这个文件(当前这个是本地的,没有触发网络请求)

效果

只要一刷新,当前这个页面JS就会被加载出来,并且被执行了.

当加载好了这个JS之后,就会立即执行

script 标签带有了 src 属性之后,script内部就不能再写其他JS代码了.写了也不生效

 如果一个页面中包含了多个 script 标签,就会按照 script 出现的先后顺序决定执行顺序.

此处最明显的体会就是 JS 是从网络上加载过来的.

这一点是非常非常有意义的.

输入输出(

输入(基本用不到,简单一说): prompt

弹出一个输入框

// 弹出一个输入框

prompt("请输入您的姓名:");

输出: alert

弹出一个警示对话框, 输出结果

// 弹出一个输出框

alert("hello");

输出: console.log

在控制台打印一个日志(供程序员看)

打印到控制到

 console.log 调试 js 程序的一个重要手段

普通用户一般都不会关注(普通用户也不会打开开发者工具)

注意: 在 VSCode 中直接输入 "log" 再按 tab 键, 就可以快速输入 console.log

 JavaScript的基本语法

全世界的编程语言,没有1000也有几百,

主要可以分为两个大类

1.类 C ,和 C 类似,命令式的编程. C++ , Java, JS......

2.类lisp 和 lisp 类似. 函数式编程

变量的创建

JS中创建的变量,不需要显示指定类型.

变量的实际类型,根据初始化/赋值来确定.

var num = 10;

var 是 js 中的一个关键字,就表示 num 是一个变量.

效果

修改变量

 

效果

效果

 注意:

把变量赋值成 数字, 就是数字类型(number)

把变量赋值成 字符串, 就是字符串类型(string)

和 var 一样, let 也是 js 的关键字

 let 是 ES6 引入的相对新的机制(ES6 大概是 201x年左右搞出来的)

var 这是最早就有(199x)

var 里面有一些缺陷

后面统一使用 let.

使用 let 之后,这个变量的作用域,生命周期啥的都和 java 中的变量都类似.

动态类型

Java是一个静态类型的语言.一个变量的类型,在编译阶段就固定了,在运行时不能改变!!

int num = 10;

num固定就是 int 类型.代码指定过程中不管把 num 咋改,始终都是 int 类型

JS 是一个动态类型的语言,变量的类型在运行时是能够改变的!

变量的类和和附的直接相关.

举例:

效果

 typeof查看变量类型

效果

 

现在代价普遍认为,还是静态类型香 

静态类型,更有利于开发工具进行分析代码.

IDEA代码补全

同样是JB家工具.IDEA的体验,远远高于PycCharm(写python) 和 WebStorm(写JS)

基本数据类型

JS 中内置的几种类型

number: 数字. 不区分整数和小数.

boolean: true 真, false 假.

string: 字符串类型.

undefined: 只有唯一的值 undefined. 表示未定义的值

null: 只有唯一的值 null. 表示空值.

number 数字类型

JS里面的数字类型包含了整数和小数!!!

效果

 数字进制表示

计算机中都是使用二进制来表示数据, 而人平时都是使用十进制.

因为二进制在使用过程中不太方便(01太多会看花眼).

所以在日常使用二进制数字时往往使用 八进制 和 十六进制 来表示二进制数字

var a = 07;      // 八进制整数, 以 0 开头

var b = 0xa;     // 十六进制整数, 以 0x 开头

var c = 0b10;    // 二进制整数, 以 0b 开头

注意:

一个八进制数字对应三个二进制数字

一个十六进制数字对应四个二进制数字. (两个十六进制数字就是一个字节)

各种进制之间的转换, 不需要手工计算, 直接使用计算器即可.

特殊的数字值

Infinity: 无穷大, 大于任何数字. 表示数字已经超过了 JS 能表示的范围.

-Infinity: 负无穷大, 小于任何数字. 表示数字已经超过了 JS 能表示的范围.

NaN: 表示当前的结果不是一个数字.

效果

 string 字符串类型

字符串字面值需要使用引号引起来, 单引号双引号均可

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"';    // 正确, 搭配使用单双引号

求长度

效果

 length是一个属性

string的 length 表示的是字符的数量,不是字节的数量

JS也支持字符串和数字之间的拼接,会尝试把数字自动转成字符串,这一点和Java也是非常相似的.

boolean 布尔类型

Java是一个强类型的语言,不太支持隐式类型装换.Java中的布尔仅仅是布尔,仅仅是真假,不能干别的事情.

JS是一个弱类型的语言,能支持一些隐式类型转换.JS中的布尔,也被当做 1 和 0

效果

undefined 未定义数据类型

如果一个变量没有被初始化过, 结果就是 undefined, 是 undefined 类型

效果

最典型的用法,就是访问js的某个对象的属性,但是这个属性又不存在.

undefined 表示是一个非法的状态.(特指没被初始化)

null是一个空值,也是表示一个非法的状态.(用户手动设定的非法值)

按理来说,编程语言里面有一个概念能够表示"非法状态" 就够了.

因此除了 JS 之外,大部分语言都是有null,但是没有 undfined

undefined 也是之中内置类型,这个类型的值只有一个,就是undefined

null也是一种内置类型,这个类型的值只有一个,就是null

 null确实是null类型,但是js始终没有修改这一点.

也可以试着对 undefined/null 进行一些运算

 运算符

算术运算符

+ - * / %

赋值运算符 & 复合赋值运算符

= += -= *= /= %=

自增自减运算符

++: 自增1 --: 自减1

比较运算符

<

>

=

== 比较相等(会进行隐式类型转换)

!=

=== 比较相等(不会进行隐式类型转换)

!== 逻辑运算

逻辑运算符

用于计算多个 boolean 表达式的值.

&& 与: 一假则假

|| 或: 一真则真

! 非

位运算

& 按位与

| 按位或

~ 按位取反

^ 按位异或

Java只能针对整数来进行

JS里位运算也是类似

移位运算

<< 左移

>> 有符号右移(算术右移)

>>> 无符号右移(逻辑右移)

上述运算符和Java不同的

===  ||

举例:

效果

 ==在比较的时候不考虑类型,会尽可能进行类型转换这样的操作

===在比较的时候会考虑比较类型.如果类型不同,就直接是false.

效果

||

JS中的逻辑或和Java1差别很大

Java || 运算返回的一定是boolen 值

JS的或运算

a || b

如果a为true,整个表达式的值就是a的值.

如果a为false,整个表达式的值就是b的值

得到的结果,不一定就是boolean

条件语句

基本语法格式

条件表达式为 true, 则执行 if 的 { } 中的代码

// 形式1

if (条件) {  

语句

}

// 形式2

if (条件) {  

语句1

} else {  

语句2

}

// 形式3

if (条件1) {  

语句1

} else if (条件2) {  

语句2  

} else if .... {    

语句...

} else {    

语句N

}

if()里的条件0表示false,非0表示true

三元表达式

是 if else 的简化写法.

条件 ? 表达式1 : 表达式2

条件为真, 返回表达式1 的值. 条件为假, 返回表达式2 的值

注意, 三元表达式的优先级是比较低的.

switch

更适合多分支的场景.

switch (表达式) {

   

case 值1:        

语句1;        

break;    

case 值2:        

语句2:        

break;    

default:        

语句N;

}

循环语句

重复执行某些语句

while 循环

while (条件) {  

循环体;

}

执行过程:

先执行条件语句

条件为 true, 执行循环体代码.

条件为 false, 直接结束循环

举例:

打印 1- 10

var num = 1;

while (num <= 10) {  

console.log(num);    

num++;

}

continue

结束这次循环

var i = 1;

while (i <= 5) {    

if (i == 3) {        

i++;        

continue;  

}    

console.log("我在吃第" + i + "个李子");  

 i++;

}

break

结束整个循环

var i = 1;

while (i <= 5) {

   

if (i == 3) {        

break;  

}    

console.log("我在吃第" + i + "个李子");    

i++;

}

for 循环

for (表达式1; 表达式2; 表达式3) {

循环体

}

表达式1: 用于初始化循环变量.

表达式2: 循环条件

表达式3: 更新循环变量

执行过程:

先执行表达式1, 初始化循环变量

再执行表达式2, 判定循环条件

如果条件为 false, 结束循环

如果条件为 true, 则执行循环体代码.

执行表达式3 更新循环变量

举例:

for (var num = 1; num <= 10; num++) {    

console.log(num);

}

小结:

变量

类型

运算符

条件

循环

绝大部分内容都和Java是差不多的

除了变量的定义

内置类型(number,string,boolean,undefined,null)

静态类型 vs 动态类型

强类型 vs 弱类型

运算符中的一些特殊的用法(===,||) 

数组 

批量创建的一组变量.

Java/C中,要求数组中的变量是相同类型的

但是JS中不要求.(其他动态类型语言中,都不要求)

创建数组的方式

1.通过new关键字来创建(非常像Java)

数组在JS中也是一个"对象"

2.实际开发中,更长使用的是,通过字面量的方式来创建.

 JS中通过 [ ] 表示数组 

 效果

 

 下标越界

效果

JS尝试读取数组中不存在的下标,就会出现 undefined 这样的结果 

JS尝试写入数组中不存在的下标,就会往这个下标插入元素,同时可能就会修改数组的长度

但是中间元素的值,相当于没有定义,仍然是undefined

效果

 

效果

 JS可以给数组指定一个字符串 类型的"下标"

此处这个 "下标" 更应该 理解成是"属性",也就是相当于"键值对"

JS数组是一个对象,对象是可以在运行时动态的新增或者删除属性的!!!

class Test{

int num;

}

JS可以在运行时给这个Test类新增一个属性,或者删除 num 属性!!

效果

 本质上是在创建一个 hello 属性.

类似的,也可以通过 [ ] 或者 . 的方式都能访问属性!!

使用 push 进行追加元素

效果

删除数组中的元素 

使用 splice 方法删除元素

效果

  

函数

函数(function)就是方法(method),方法就是函数.

如果要去咬文嚼字,

function 指的是一个独立的函数

method  指的是某个类/对象的成员函数

函数语法格式

函数的调用没什么区别,定义这里的区别较大

 

 函数的定义涉及到一个关键字 function 这是 JS中的关键字,表示接下来这是个函数定义.

不必写函数的返回值类型

函数的形参列表只有形参名,没有形参类型

 Java中不涉及这个问题(大家都是成员函数)

C语言中有这个问题:函数的定义得在函数调动的上头,如果不是的话,就需要来个函数声明.保证调用的时候编译器知道自己在调用个啥.

 正因为函数参数不必写类型,实际传参的时候,传啥类型都行

只要传入的参数能够支持函数体里的逻辑即可.

像JS这种动态类型的语言,不需要"泛型"这样的语法.

动态类型的语言,一般也不需要"多态"这样的机制

多态的本质是,让用户不知道引用实际是啥类型,也能调用里面的方法....是封装的更进一步

这种事对于动态类型语言来说,都是天然就支持的.

知识补充:

啥是多态,多态到底能干啥,多态能解决啥问题.

面试中的常见问题

形如这种比较抽象的问题,回答的方案:举例子!!!

实际遇到的例子!!!

1.集合类

List<String> list = new ArrayList<>()

list.add(.....);

2多线程

继承Thread,重写Runnable,都得提供 run 方法.

JVM 内部调用 父类的 run,执行到用户自己定义的 run

3网络

回显服务器,又进一步的基于回显服务器实现了字典服务器.

重写了 process 方法..

参数个数

 在C/Java这样的语言中,要求函数定义时形参的个数好调用实参的个数匹配!!

(变长函数除外,printf(这是通过特殊手段实现的))

但是JS没有这个要求

效果

 JS对于实参和形参的个数并没有明确的约束.

也就导致在写函数的时候,就可以灵活应对

效果

 正因为JS这里的参数设定非常灵活,因此JS根本不需要"函数重载"

函数表达式 

定义一个函数,然后把这个函数赋值给一个变量.

然后就可以使用这个变量来调用这个函数了

定义了一个函数,叫做addFunc

然后把这个函数赋值给了一个变量!

(Java是做不到这一点的,Java中的函数不能独立存在) 

JS里面函数是"一等公民"

函数和一个普通的变量类似,可以相互赋值.

还可以作为另一个函数的参数

还可以作为另一个函数的返回值.

赋值之后,就可以完全使用add代替addFunc这个函数名了.

因此就可以把addFunc这个名字给省略掉!

定义了一个匿名(没有函数名)的函数,把这个函数赋值给了另一个变量

此时就可以拿这个变量来进行函数调用了

作用域 

JS中的作用域

和Java也差距比较大.

不同的定义变量的方式,有区别

var 定义的变量,没有块级作用域.

let 定义的变量,有块级作用域.(代码块级别的,{ } 限制作用域)

效果

在大括号外面,但是仍能打印,如果把 var 换成 let 就不可以了,就会报错.

作用域链 

因为 JS 里面的函数内部还能定义函数.

然后某个函数内尝试使用的变量,就会沿着这个函数定义的嵌套关系,逐渐一直往上找,一直找到最顶层的全局作用域.

结果

执行 console.log(num) 的时候, 会现在 test2 的局部作用域中查找 num. 如果没找到, 则继续去 test1 中 查找. 如果还没找到, 就去全局作用域查找. 

 对象

早期的JS的“对象”和Java 差别很大

然后从ES6标准开始,逐渐在向 Java 靠拢

在ES6之前,JS中没有“类”这样的概念!!!只有对象!!!

之前的 JS 就觉得每个对象都是一个独立的个体。

即使是有一些关联,这样的关联也通过其他来完成.

也就意味着 JS 中没有"继承",也没有public/private,也没有多态,也没有反射.....

从ES6开始,也引入了class,引入了继承,有了构造方法....但是其他的还是没有.

对象的创建

1. 使用 字面量 创建对象 [常用]

对象定义好了之后,就可以使用对象的属性和方法

1.还是通过 点 进行成员访问操作

2.还可以通过 [ ] 类似于取下标的方式来访问 

2. 使用 new Object 创建对象

JS 的对象都可以视为是Object类型

就可以通过new Object 来创建一个object 实例来.

 

如果需要创建多个"类似"的对象出来.

使用上面的方式就有点麻烦.

就可以搞一个函数,把对象创建的过程,来封装一下. 

 

JavaScript 对象没有 "继承" 继承本质就是 "让两个对象建立关联". 或者说是让一个对象能够重用另一个对象的属性/方法. JavaScript 中使用 "原型" 机制实现类似的效果. 

原型机制,相当于 "JS引擎,给JS程序猿留下的一个后门"

类似于,反射机制,也相当于 JVM 给 Java 留下的一个后门

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

K稳重

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值