JavaScript总结(基础篇)

前言

最近花了三天的时间,系统地学习了一下JavaScript,由于之前有一些编程语言基础,并且学的都是一些基础内容,所以相对来讲学的比较快,学习方法主要是通过看B站视频和阅读《JavaScript语言精粹》来进行学习,学习的版本是ES5的版本,在此想要做个总结文档,来对这三天的学习进行总结,本文结构分为:对JavaScript的认识、JavaScript核心语法、JavaScript各种结构、数组、函数以及对象。适合有JAVA基础的读者进行参考。

一、对JavaScript的认识

在阅读了《JavaScript语言精粹》这本书的前言以及第一章后,我能够认识到,JavaScript是默认的"网页语言",他是一个轻量级、弱类型的语言,它与浏览器的结合使他成为世界上最流行的编程语言之一。

另一方面,JavaScript存在着许多"糟粕",实际上,JavaScript的很多设计是很鸡肋的,一方面是很多设计不够规范,另一方面就是设计者的一些设计错误。在我的学习过程中,我也能发现很多设计相对于其它的一些编程语言着实有些令人费解。当然了,我们需要注重学习的还是其精华部分。这里借用一句作者说的话,"在JavaScript中,美丽的,优雅的,富有表现力的语言特性就像珍珠和一些鱼目混杂在一起一样。" JavaScript包含ECMAScript(JavaScript语法)、DOM(页面文档对象模型)、BOM(浏览器对象模型)。下文的内容主要是根据ECMAScript展开的。

二、JavaScript核心语法

1.变量:

在JavaScript中,变量的声明是通过var、let、const进行的,其中,let是ES6后才引入的,后文会详细讲,它能够声明块级作用域变量。下文主要通过与Java对比来阐述JavaScript的变量

  1. 与Java不同的是,JS的变量无需指定类型 ,JS会自动识别类型,这点其实跟PYTHON很像,如果想要查看变量的类型,我们可以通过typeof 变量来进行查看。
  2. 声明变量时(以var举例),我们可以通过var a = 1 和 a = 1来声明,推荐使用前者(显式声明);声明多个变量时,我们可以通过var a=1,b=2,c=3来声明,也可以通过var a=1;b=2;c=3来声明,但是最好不要用var a=b=c=1这种方式来声明。
  3. JS的变量声明后会占用一块内存,每一次新var一次,则会产生新的内存,这里我们要区分,var a = 1之后进行a = 2不会占用新的内存,只是会修改原有内存的值。我们还要注意,var a = 1之后进行b = a会让b复制a的值,修改b不会影响a。如下
ini 复制代码
var a = 1;
b = a;
b = 2;
console.log(a)  //1

JS中,var,let,const很多情况下是可以相互替换的,那么我们何时使用哪个呢?以下是读者后来的经验以及结合DeepSeek总结出来的一套规范

现代JS变量声明规范
优先使用const

默认一些不需要重新赋值的变量或者常量: 包括:数据,对象,Map,Set,函数表达式以及常量(例如pai)

ini 复制代码
const PI = 3.14159;
const user = { name: "Alice" };
const numbers = [1, 2, 3];
const map = new Map();
const set = new Set();
const sayHello = () => console.log("Hello");

如果遇到一些基本的数字变量或者字符串变量 可能需要重新赋值 咱们就使用let

ini 复制代码
let counter = 0;
counter++; // 允许

let result;
if (condition) {
  result = computeSomething();
} else {
  result = fallbackValue();
}

为什么不推荐使用var,因为我们知道 var会存在预解析(变量提升)造成一些不必要的麻烦,以及因为var是全局变量,可能会带来一些性能上和内存上的开销

如果确定要使用var,一般是在确定要使用全局变量的情况下,那么咱们一般在最前面声明全局变量即可

2.数据结构

  1. JavaScript中,数据结构主要分为数字型和字符型,布尔型,其中数字型只有一种基本类型Number,包含整数和浮点数,没有单独的整数类型。它的类别不像Java那么多(存在Float、int、long等等),我们可以利用isNaN来判断是否为数字型。
  2. 通常来说创建变量指定值后,JS会自动识别类型,但是当创建变量没有定义值时,变量会变成undefined。 这里需要区分一下NULL和undefined,对于NULL来说,他是开发人员显示声明的空值,实际上,他是人为赋值的,typeof null的结果为object,而typeof undefined的结果为undefined

3.下面是数字类型和字符串类型之间相互的转换:
1.转换为字符串类型

方法一

ini 复制代码
var num = 3;
num = 3 + "" //此时就会将num转换成字符串类型

方法二

ini 复制代码
var num2 = 6;
num2 = String(num2); //利用字符串转换函数

2.转换为数字类型

方法一

ini 复制代码
var str = "9";
str = parseInt(str); //利用parseInt或者parseFloat进行转换
console.log(typeof str)

方法二

ini 复制代码
var str2 = "10";
str2 = Number(str2)  //利用Number进行转换
console.log(typeof str2)

方法三(重点)

ini 复制代码
var str3 = "22";
str3 = str3 - 12;  //利用- * / 进行隐式转换
console.log(typeof str3)

注意:在浏览器的控制台中,Number一般是蓝色,String一般是黑色,null,undefined一般是灰色

3.运算符

运算符这里其实各个语言都是差不多的,本文主要提三点需要注意的地方
1.前置递增运算符和后置递增运算符的区别

前置递增运算符是先++ 后赋值 后置递增运算符是先赋值 后++

举个例子趴

ini 复制代码
var age1 = 10;
var age2 = 10
console.log(age1++ + 10);  //后置 先赋值10 输出20
console.log(++age2 + 10);  //前置 先加成11 输出21

2.比较运算符
=====的区别:

前者是严格比较:需要比较类型的同时比较值

后者是默认转换类型后比较

ini 复制代码
var a = "3";
console.log(Boolean(a === 3)) //这里返回false 因为字符串类型和数字类型不同
console.log(Boolean(a == 3)) //这里返回true 因为JS的==会转换类型后比较值 发现相同

3.逻辑 && 与 ||

javascript 复制代码
//1. 逻辑与  表达式1 && 表达式2  如果表达式1 值为真 则返回表达式2 如果表达式1 值为假 则返回表达式1
console.log(123 && 456)  //返回456
console.log(0 && 1 && 2 && 3)  //返回0
console.log(undefined && 23) //返回undefined
console.log(null && 23) //返回null
//2. 逻辑或 表达式1 && 表达式2 如果表达式1 值为真 则返回表达式1 如果表达式1 值为假 则返回表达式2
console.log(123 || 456) //返回123
console.log(undefined || 77 || 88 || 99)  //返回77

三、JavaScript各种结构

1.if分支结构

if的语法和java一样,都是使用if(表达式){代码片段}。下面举一个经典的计算分数来巩固

xml 复制代码
<script>
  var score = parseInt(prompt("请输入你的分数"));
  // 根据分数进行判断
  if (score >= 90)
  {
    console.log("A");  //如果语句长的话可以用{},短的话可以不用
    console.log("你太优秀啦 快来领取奖励!")
  }
  else if (score >= 80)
    console.log("B");
  else if (score >= 70)
    console.log("C");
  else if (score >= 60)
    console.log("D");
  else
  console.log("E")
</script>

2.switch语句

这个也是和Java很像,下面引出一段代码 来巩固

dart 复制代码
var num = prompt("输入")
num = parseInt(num)
switch (num){
  case 1:
    alert("666");
    break;  //注意一定要写break  符合规范,并且不容易出错
  case 3:
    alert("succeed!")
    break;
  default:
    alert("saf" + num)
}

关于if分支和switch其实可以相互替换,各自根据不同的场景进行使用:如果根据表达式判断稍微复杂一点的内容,推荐使用if;而如果对某个变量进行判断,推荐使用switch

3.for循环

JS中的for循环仍旧和java的语法极度相似,我们使用类比的方式来呈现,就能看到他们有多像了
求1-100之间所有数的和

Java代码:

ini 复制代码
int sum = 0;
for (int i = 1; i <= 100; i++) {
    sum += i;
}
System.out.println(sum);

JavaScript代码:

ini 复制代码
var sum = 0;
for (let i = 1; i <= 100 ; i++) {
  sum += i;
}
console.log(sum)

拓展几个常用的for

  1. for of
typescript 复制代码
var str1 = [1,2,3];  //数组中常用的遍历方法 当然也可以用传统的fori模型 还可以遍历(Map,Set,Sting等)
for (const number of str1) {
  console.log(number)
}
  1. for in
arduino 复制代码
const mymap = {
  name:'zangsa',
  age:15
}  //对象常用的遍历方法 遍历的是对象的键
for (const mymapElement in mymap) {
  console.log(mymapElement)
}

JS中的for循环需要注意一个点:for循环括号里面最好使用let声明变量i,因为变量i没必要放到全局中,所以我们不推荐使用var。

4.while循环

同样地,我们将类比Java和JavaScript的方式来进行学习while的使用
打印人的一生,从一岁到一百岁

java语法:

csharp 复制代码
int i = 1;
while(i <= 100){
    System.out.println("我" + i + "岁啦!");
    i++;
}

JavaScript语法

css 复制代码
var i = 1
while (i <= 100) {
  console.log('我' + i + '岁啦!');
  i++;
}

这里提一下:上述if、for、switch、while各自结构里面的{}的变量就是一个我们上文提到的块级作用域,实际上如果用let声明:执行完块的内容 则变量会变得不可用,如果用var声明:执行完块的内容 变量的值仍然存在

四、数组

1.数据的创建方式

数据的创建方式有两种:

第一种是通过var arr = new Array(),使用此方式可以创建一个空的数组,第二种是通过var arr = [1,2,3.14,'zhangsan',true,'wangwu']

2.数组可以存放不同的数据类型

在JS的数组中,可以存放不同类型的数据,这点和JAVA很不相同,java需要明确定义数组的类型并且不能存放不同类型的数组。而JS的数组比较灵活,我们完全可以存放各式各样的元素,也可以创建一个空数组

3.数组的获取以及遍历

获取数组元素是使用[]下标的方式即可,和JAVA一样,从0开始存放第一个元素,length代表数组的长度

ini 复制代码
var arr = [1,2,'yao',true];
console.log(arr[2]);  //输出"yao"
console.log(arr.length)  //输出4

数组的遍历案例

ini 复制代码
//求数组的最大值
tempArr = [2,6,1,77,52,25,7]
let max = 1;
for (const ele of tempArr) {
  if(ele > max)
    max = ele;
}

4.二维数组的创建

在我们以后的应用中,肯定经常会使用到二维数组的创建,所以单独拎出来讲讲二维数组的创建 创建3行3列值全为0的数组

const 复制代码
const cols = 3;
const matrix = [];
for (let i = 0; i < rows; i++) {
    matrix[i] = []; // 初始化第 i 行
    for (let j = 0; j < cols; j++) {
        matrix[i][j] = 0; // 填充 0
    }
}
console.log(matrix); // [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

5.数组的引用知识

数组实际上我们使用typeof会发现它是一个对象,所以它是可以引用的,引用:可以使两个变量指向同一块内存区域,更改值实际上是更改同一块内存区的值

perl 复制代码
var arr1 = ['green', 'blue', 'yellow'];
var arr2 = arr1;          // arr2 直接引用 arr1 的内存地址
console.log("arr2直接引用arr1:" + arr2); // ["green", "blue", "yellow"]

arr2[1] = 'ggg';          // 修改 arr2 会影响 arr1
console.log("arr2修改后 arr1的结果:" + arr1); // ["green", "ggg", "yellow"]

如果我们不想引用,只是想复制目标数组,JS提供了以下的方法,我测试了都是可行的

css 复制代码
var arr2 = [...arr1]; // 创建新数组,复制元素
arr2[1] = 'ggg';
console.log(arr1); // ['green', 'blue', 'yellow'](不受影响)
console.log(arr2); // ['green', 'ggg', 'yellow']

var arr2 = arr1.slice(); // 复制数组
arr2[1] = 'ggg';
console.log(arr1); // ['green', 'blue', 'yellow'](不受影响)
ini 复制代码
如果用var定义 数组 再用let引用数组 会怎么样? 答:实际上无影响 仍然会引用
var str1 = [1,2,3];
let str2 = str1;
console.log("str2的值是" + str2);  1,2,3

str2[0] = 6;
console.log("str1修改后的值是" + str1) 6,2,3

五、函数

函数我觉得算是JavaScript的一个重难点之一了,它与java的函数也不是很像,所以学过java的读者可以将重心放在JavaScript的函数这边

1. 函数的创建方式

函数的创建方式有两种,第一种是

javascript 复制代码
//函数声明:创建有名函数
function sayHello(){
  console.log("Hello")
}

第二种是

javascript 复制代码
//函数表达式:创建匿名函数
const sayHello = function(){
  console.log("Hello");
}

上述两种方式都是定义函数的方式,我们都可以通过sayHello()来调用具体的函数

何时使用哪种方式?

当需要提升(预解析)时,或者需要给函数命名时,一般情况下优先使用函数声明

当需要动态赋值、作为回调函数或者需要将函数作为变量传递时,使用函数表达式

现代JavaScript避免使用var声明函数表达式,而是使用const或者let来避免变量提升

2.函数的作用域

在ES5和ES6中,在函数内声明的var变量作用域都只存在于函数内部,超出函数无法访问,实际上ES6引入的letconst都是作用于块级作用域,与函数无关。

3.函数的参数

函数的形参不需要指定类型,形参的个数和实参要一样,但是其不会像java一样严格要求数量与类型要一致。若形参与实参的个数不匹配,会产生一系列问题

javascript 复制代码
如果实参个数 > 形参的个数
会正常取到形参的个数

如果实参个数 < 形参的个数
多余的形参定义为undefined(把形参看成变量,定义后没有赋值)

函数还存在一个默认的arguments:传入的参数集合

javascript 复制代码
var souta = function() {
  console.log(arguments)
}
souta(1,2,3,4,5) //会输出1,2,3,4,5

4. 函数的返回值

在JS中,函数可以定义返回值,也可以不定义返回值

如果不定义返回值,使用变量取函数的话,则会取到undefined

javascript 复制代码
function fn(){
  console.log("我就只输出 不返回值")
}
var tempFn = fn();
console.log(tempFn)
//此时控制台会输出 "我就只输出 不返回值"和undefined

当然了,函数也可以通过return设置返回值,语法和java也是类似的

return最多只能返回一个值,下面是return的一个应用

javascript 复制代码
function fn2(){
  console.log("我不仅输出,我还返回值")
  return 666;
}
var getFn2 = fn2();
console.log(getFn2)

5.箭头函数(ES6新特性)

下面是箭头函数的一些用法和特性
箭头函数的用法

javascript 复制代码
// 普通函数
function sum(a, b) {
  return a + b;
}

// 箭头函数
const sum = (a, b) => a + b;

// 普通函数
function get(a){
    return a;
}
// 箭头函数
const get = a => a; //箭头后面是要return的内容 单条参数可省略


const sayHi = () => {   //若使用箭头函数 无参的话记得保留括号
  console.log("Hi");
};  

箭头函数的特性

1.箭头函数不绑定自己的this

javascript 复制代码
const person = {
  name: "Alice",
  sayName: function() {
    console.log(this.name); // 正常输出"Alice"
  },
  sayNameArrow: () => {
    console.log(this.name); // 输出undefined(this指向外层作用域)
  }
};

2.箭头函数不绑定arguments对象

js 复制代码
const showArgs = () => {
  console.log(arguments); // 报错:arguments is not defined
};
showArgs(1, 2, 3);

显而易见,我们会发现箭头函数适合回调函数(一个函数作为参数传递给另一个函数),不适合对象的构造函数。

六、对象

JS中的对象是一组无无序的相关属性和方法的集合,所有的事务都是对象,例如字符串,数值,数组,函数等。和JAVA一样,对象是需要创建的,这里我学习的版本是ES5,同时也比较基础,所以咱们讨论的是不存在类的情况。

1.对象的创建方式

JS中对象有三种创建方式:

  1. 方式一:var obj = new Object()
  2. 方式二: var obj = {name: 'zhangsan',age: 18 }
  3. 方式三:var obj = new Constructor(name,age)

2.JS在ES5中的对象和JAVA的关联

JS中关于对象的部分 其实和JAVA 可以关联着记忆:

  1. JAVA中存在着类,对象一般是创建某个类的对象,而JS不存在类的概念,JS中的构造方法和类很像,可以将其理解成类
  2. 不论是JAVA创建某个类的对象,还是JS中利用构造方法方便地创建对象 我们都称之为实例化
  3. JS跟JAVA还有些不同的是:不需要定义类,可以直接创建对象。并且不会报错

3.对象的构造方法

kotlin 复制代码
function WzryRole(name,type,blood,attack){
  this.name = name;
  this.type = type;
  this.blood = blood;
  this.attack = attack;
  this.operation = function(){
    console.log("已选择" + this.name + "的类型是" + this.type + ",他的血量为" + blood + ",他的攻击方式是" + attack)
  }
}

需要注意的几点

  1. 对象的构造方法要符合驼峰命名,适当使用大写;
  2. 在调用对象的构造方法时,需要加上new关键字
  3. 在对象的构造方法里面 一定要记得加this

4.对象的遍历和取值

对象的遍历推荐使用for in,遍历的是对象的key ,我们可以通过obj[key]来获取值

javascript 复制代码
var NZ = new WzryRole("哪吒","战士",1666,"乾坤拳");
for (const nzKey in NZ) {
  console.log("对象的key是" + nzKey);  //name,type,blood,attack operation
  console.log("对象的value是" + NZ[nzKey]) // 哪吒 展示 1666 乾坤拳 function(){con...}
}

在以后的使用中,在某些简单的情况下,可以把对象当map使用,实际上,这样做可以存储不重复的key、也可以根据key获取值,时间复杂度为O(1)

七、总结

整个这是本人在掘金发的第一篇博客,所以文中有许多不足,后续会改进,本文内容内容主要是参考B站BV1ux411d75J,《JavaScript语言精粹》、以及DeepSeek。

相关推荐
anyup_前端梦工厂34 分钟前
React 单一职责原则:优化组件设计与提高可维护性
前端·javascript·react.js
龙萌酱2 小时前
力扣每日打卡17 49. 字母异位词分组 (中等)
前端·javascript·算法·leetcode
jingling5552 小时前
前端开发核心知识详解:Vue2、JavaScript 与 CSS
javascript·css·vue.js
AronTing2 小时前
单例模式:确保唯一实例的设计模式
java·javascript·后端
Cutey9163 小时前
Vue 中的高阶函数:提升代码复用与组件抽象的利器
前端·javascript·面试
Bunury4 小时前
element-plus添加暗黑模式
开发语言·前端·javascript
辣椒粉丝4 小时前
记rspack想提issuse,提太慢白嫖不上了
前端·javascript
七月丶4 小时前
🧼 为什么我开始在项目里禁用 CSS 文件?
前端·javascript·后端
好柿会發生4 小时前
关于chartjs的简单使用,各位大佬有知道什么办法通过js设置图表的宽高嘛
javascript·vue.js