JavaScript 基础

在这里插入图片描述

什么是JavaScript

JavaScript 是一种高级的、解释型的编程语言,通常用于客户端脚本,允许开发者在浏览器中创建动态、交互式内容。它是前端开发的核心技术之一,与 HTML 和 CSS 并驾齐驱,共同构成了现代网页开发的基础。

HTML、CSS、JavaScript之间的关系:

在这里插入图片描述

JavaScript 的运行过程

  1. JavaScript编写的代码是保存在文件中的,也就是存储在硬盘(外存上)
  2. 双击 .html 文件,浏览器(应用程序)就会读取文件,将文件内容加载到内存中
  3. 浏览器会解析用户编写的代码,将代码翻译为二进制的,能让计算机识别的指令
  4. 得到的二进制指令会被 CPU 加载并执行

在这里插入图片描述
浏览器分为渲染引擎 + JS 引擎:

  • 渲染引擎:解析 HTML + CSS,俗称“内核”
  • JS 引擎:也就是 JS 解释器,典型的就是 chrome 中内置的 V8

JavaScript 的组成

JavaScript 由下面的内容组成:

  1. ECMAScript(简称 ES):JavaScript 语法
  2. DOM:页面文档对象模型,对页面中的元素进行操作
  3. BOM:浏览器对象模型,对浏览器窗口进行操作

光有 JS 基础语法,只能写一些基础的逻辑流程,要想完成更为复杂的操作,完成浏览器以及页面的交互,就需要 DOM API 和 BOM API。

JavaScript 的书写方式

JavaScript 和 CSS 类似,都有三种书写方式:

1. 行内式

直接将 JS 嵌入到 HTML 元素内部:

<input type="button" value="JavaScript样例" onclick="alert('hello world!')">

在这里插入图片描述
该方式只适合写较少且较短的 JS 代码。

2. 内嵌式

将 JS 代码写在 script 标签中:

<script>
    alert('hahahahahah')
</script>

在这里插入图片描述

3. 外部式

可以将所有的 JS 代码都写入到一个 .js 文件中,然后通过 <script src=""></script> 来引入 js 文件:

<script src="hello.js"></script>
alert('你好!')

在这里插入图片描述

注释

JavaScript 注释分为单行注释——\\ 和 多行注释——/* */

// 我是单行注释
/*
我是多行注释
我是多行注释
我是多行注释
*/

输入输出

JavaScript 输入使用 prompt('提示词')

<script>
    prompt('请输入你的名字')
</script>

在这里插入图片描述
JavaScript 的输出分为两种,一种是弹出警示框输出alert('输出内容'),一种是输出在控制台console.log('输出内容')

<script>
    alert('你好')
</script>

在这里插入图片描述

<script>
    console.log('你好')
</script>

f12 打开控制台:

在这里插入图片描述

JavaScript 变量

JavaScript 中创建变量可以使用 var 关键字和 let 关键字,这两个关键字的区别不大,但是建议使用 let 来创建变量,因为 let 的出现是晚于 var 的,功能更强大。

<script>
    var name = '张三';
    let age = 18
</script>

每个 JS 语句后面都以分号 ; 作为结束的标志,但是在 .js 文件中每一个语句后面的分号是可以省略的。

<script>
    let name = prompt('请输入您的名字:');
    alert('你好' + name);
</script>

在这里插入图片描述
在这里插入图片描述
可以发现,JavaScript 定义变量的时候,只需要使用 var 或者 let 关键字就可以,而不需要指定变量的类型,换句话说就是:JavaScript 是弱类型的语言,也就是动态类型的语言。

JS 的变量类型是程序运行过程中才可以确定的,只有运行到 = 的语句的时候才可以确定变量的类型。

<script>
    var a = 10;
    var b = 'haha';
</script>
<script>
    var a = 10;
    console.log('a的数据类型为:' + typeof(a));
    a = 'haha'; //在程序运行的过程中,变量的类型可能会发生变化
    console.log('a的数据类型为:' + typeof(a));
</script>

在这里插入图片描述

var 定义的变量和 let 定义的变量的区别

作用域(Scope):

  • var声明的变量具有函数作用域或全局作用域。在函数内部使用var声明的变量,只能在该函数内部访问,但如果在函数外部(全局作用域)使用var声明变量,则可以在整个脚本中访问它。然而,需要注意的是,由于变量提升(Variable Hoisting)的原因,var声明的变量可以在其声明的代码之前就被访问,但此时它的值是undefined。
  • let声明的变量具有块级作用域(block scope)。这意味着变量只在其声明的代码块(如{}内部)内有效。在块外部无法访问到该变量。此外,let声明的变量不存在变量提升,也就是说,它不能在声明之前被访问。

生命周期(Lifetime):

  • var声明的变量在函数执行完毕或脚本执行完毕后不会立即被销毁,而是会保留在内存中,直到窗口或标签页被关闭。这就是所谓的闭包(Closure)现象,即函数外部无法访问函数内部的var变量,但函数内部可以访问函数外部的var变量。
  • let声明的变量在块执行完毕后会被销毁(除非被封闭在闭包中)。这意味着let变量具有更精确的生命周期控制。

重复声明:

  • 使用var可以重复声明同一个变量,而不会报错,但这样做会导致之前的值被覆盖。
  • 使用let不能在同一作用域内重复声明同一个变量,否则会抛出语法错误(SyntaxError)。

暂时性死区(Temporal Dead Zone, TDZ):

  • let变量在声明之前(在块或函数内)处于一个“暂时性死区”(Temporal Dead Zone, TDZ)。在这个区域内,变量是不可用的,访问它会抛出一个引用错误(ReferenceError)。这是let的一个重要特性,有助于捕获常见的编码错误。
<script>
    var num = 10;
    if (true) {
        var num = 20;
        console.log(num);
    }
    console.log(num);
</script>

在这里插入图片描述
var 只会在遇到函数的时候,函数的{}内部的区域才会被认为是一个作用域,所以在 if 语句块内的 var num 和 if 语句块之外的 var num 是同一个变量,他们的作用域是相同的。

<script>
    let num = 10;
    if (true) {
        let num = 20;
        console.log(num);
    }
    console.log(num);
</script>

在这里插入图片描述
使用 let 定义的变量,当遇到 {} 的时候,就会被认为是在一个新的作用域,所以 if 语句块之外的 let num 和 if 语句块之内的 let num 不是一个变量,两个变量的作用域不同。

JavaScript 基本数据类型

JavaScript 内置的几种数据类型:

  1. number:数字类型,不区分正数和浮点数
  2. string:字符串类型
  3. boolean:true 真,false 假
  4. undefined:只有唯一的值 undefined,表示未定义的值
  5. null:只有唯一的值 null,表示空值

number 数字类型

JavaScript 中不像 c++ 和 Java 那样区分浮点型和整型,统一都是“数字类型”。

<script>
    let num = 1;
    console.log('num的数据类型:' + typeof(num));
    num = 3.14;
    console.log('num的数据类型:' + typeof(num));
</script>

在这里插入图片描述

数字不止有我们日常使用的十进制,也可以通过 0o 前缀和 0x 前缀 和 0b 前缀分别表示八进制、十六进制和二进制:

<script>
    let num = 0o1237;
    console.log(num);
    num = 0x123a;
    console.log(num);
    num = 0b010101;
    console.log(num);
</script>

在这里插入图片描述
JavaScript 中特殊的数字

  • Infinity:无穷大,大于任何数字。表示数字已经超过了 JS 能表示的范围
  • -Infinity:负无穷大,小于任何数字。表示数字已经超过了 JS 能表示的范围
  • NaN:表示当前的结果不是一个数字
<script>
    let num = Number.MAX_VALUE; //得到Number所能表示的最大范围
    console.log(num);
    console.log(num * 2); //超过了Number能表示的最大范围,所以得到Infinity
    console.log(-num * 2);
    console.log('haha' - 10); //得到NaN
</script>

在这里插入图片描述

注意:

  • 负无穷大和无穷小不是一回事,无穷小指无限趋近于0,值为 1 / Infinity
  • ‘hehe’ + 10 得到的不是 NaN,而是 ‘hehe10’,会隐式的将数字转换为字符串类型,再进行字符串拼接
  • 可以使用 isNaN 函数判断一个变量是否不是一个数字

string 字符串类型

JavaScript 中的字符串和 python 类似,使用单引号或者双引号包裹起来的都可以称为是字符串。

<script>
    let s = '你好';
    console.log('s的数据类型' + typeof(s));
    s = "hello";
    console.log('s的数据类型' + typeof(s));
    s = haha; //报错
    console.log('s的数据类型' + typeof(s));
</script>

在这里插入图片描述
正是因为 JavaScript 单引号和双引号都可以表示为字符串,所以在字符串中表示引号就比较方便:

<script>
    console.log("女神对我说:'我爱你'");
    console.log('女神对我说:"我爱你"');
</script>

在这里插入图片描述

当然,使用转义符表示引号也是可以的:

<script>
    console.log("女神对我说:'我爱你'");
    console.log('女神对我说:"我爱你"');
    console.log("女神对我说:\"我爱你\"");
    console.log('女神对我说:\'我爱你\'');
</script>

在这里插入图片描述

字符串类型的常用的属性和方法

length属性

每个字符串默认存在一个 length 属性用来记录字符串的长度:

<script>
    let num = 'hello';
    console.log('num的长度为:' + num.length);
    num = '你好';
    console.log('num的长度为:' + num.length);
</script>

在这里插入图片描述

JavaScript 字符串中的 length 属性记录的是字符串的字符个数,而不是字节个数,所以我们的中文字符串的长度也就是汉字的个数。

字符串拼接

JavaScript 字符串拼接可以直接使用 + 来实现:

<script>
    let s1 = 'hello';
    let s2 = ' world';
    console.log(s1 + s2);
</script>

在这里插入图片描述
在要拼接的两个变量中只要有一个是字符串类型,那么最终拼接之后的结果就是字符串:

<script>
    let s1 = 'hello ';
    let s2 = 20;
    console.log(s1 + s2);
</script>

在这里插入图片描述

boolean 布尔类型

JavaScript 和其他编程语言一样 boolean 类型的取值只有真(true)和假(false),但是和一些语言不同的是:JavaScript 的布尔类型值可以参与计算:

<script>
    console.log(true + 1);
    console.log(false + 1);
</script>

在这里插入图片描述
在 JavaScript 中 true 可以表示为数字1,fasle 可以表示为数字0。

undefined 未定义数据类型

如果一个变量在定义的时候没有初始化,那么该变量的类型暂时就是 undefined 类型:

<script>
    let val;
    console.log("val的数据类型是:" + typeof(val));
    val = 'abc'
    console.log("val的数据类型是:" + typeof(val)); //对变量赋值之后就可以确定变量的数据类型了
</script>

在这里插入图片描述
undefined 类型的值是 undefined,当 undefined 数据类型的变量和字符串进行 + 的时候,就会进行字符串的拼接:

<script>
    let val;
    console.log(val + '你好');
</script>

在这里插入图片描述
undefined 数据类型的变量和数字进行相加,得到的结果是 NaN:

<script>
    let val;
    console.log(val + 10);
</script>

在这里插入图片描述

null 空值类型

在对变量进行赋值的时候,如果赋值的是 null,那么就表示该变量的数据类型是空值类型:

<script>
    let val = null;
    console.log(val + 10);
    console.log(val + '你好');
</script>

在这里插入图片描述

运算符

算术运算符
在这里插入图片描述
赋值运算符

在这里插入图片描述
字符串运算符

在这里插入图片描述
比较运算符

在这里插入图片描述
这里强调一下 ===== 的区别,==在进行比较的时候会进行隐式类型的转换,而 === 则不会进行隐式类型转换,也就是是说 === 不仅比较变量的值相等,还会比较变量的类型相等:

<script>
    let val1 = 10;
    let val2 = '10';
    console.log(val1 == val2);
    console.log(val1 === val2);
</script>

在这里插入图片描述
在使用 == 比较的时候,数字 10 首先会进行类型的转换,10 转换为 ‘10’,然后两者再比较的结果就是相等的了,而 === 比较的就是 10 和 ‘10’,所以结果就是 false。

条件运算符

在这里插入图片描述
跟 Java 的三目运算符是一样的。

逻辑运算符

在这里插入图片描述
位运算符

在这里插入图片描述

条件语句

if (条件1) {
    语句1
}else if (条件2) {
    语句2
}
...
else {
    语句n
}
<script>
    let year = parseInt(prompt('请输入年份:'));
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
        alert('闰年');
    }else {
        alert('不是闰年');
    }
</script>

在这里插入图片描述
在这里插入图片描述

switch 选择语句

跟 Java 一样,通过使用 switch 来实现选择语句:

<script>
    let day = parseInt(prompt('请输入数字'));
    switch(day) {
        case 1: 
            alert('星期一');
            break;
        case 2:
            alert('星期二');
            break;
        case 3:
            alert('星期三');
            break;
        case 4:
            alert('星期四');
            break;
        case 5:
            alert('星期五');
            break;
        case 6:
            alert('星期六');
            break;
        case 7:
            alert('星期日');
            break;
        default: //如果前面的情况都不满足的话就执行default中的语句
            alert('您输入的数字非法,请检查后重新输入!');
    }
</script>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

循环语句

JavaScript 中表示循环结构的方式有两种:while 和 for。

while (条件) {
	循环体;
}

执行过程:先判断条件语句是否为 true,为true才进入循环,否则不进入。

for (表达式1; 表达式2; 表达式3) {
	循环体;
}
  • 表达式1:用于初始化循环变量
  • 表达式2:循环条件
  • 表达式3:更新循环变量

执行过程:

  • 先执行表达式1初始化循环变量(表达式1也可以为空语句)
  • 再执行表达式2,判断循环变量是否符合条件,如果表达式2的结果为true才进行循环,否则结束循环
  • 执行完循环体中的语句之后,执行表达式3

循环结构中常用的关键字:break 和 continue。

break 用于跳出循环,当执行到 break 的时候,该此循环中的 break 之后的代码将不会执行,直接跳出循环,结束循环。

continue 用于结束本次循环,继续下一次循环,当执行到 continue 语句的时候,该次循环 continue 之后的代码将不会执行了,继续下一次循环:

<script>
    for (let i = 0; i < 10; i++) {
        console.log(i);
        if (i == 3) {
            continue;
        }
        console.log(i);
    }
</script>

在这里插入图片描述

<script>
    for (let i = 0; i < 10; i++) {
        console.log(i);
        if (i == 3) {
            break;
        }
        console.log(i);
    }
</script>

在这里插入图片描述
注意:当我们在 while 循环中使用 continue 的时候,在 continue 之前需要更改循环变量,否则就会死循环:

<script>
    let i = 0;
    while (i < 10) {
        console.log(i);
        if (i == 3) {
            continue;
        }
        console.log(i);
        i++;
    }
</script>

在这里插入图片描述
要先避免死循环,就需要在本次结束循环之前修改循环变量:

<script>
    let i = 0;
    while (i < 10) {
        console.log(i);
        if (i == 3) {
        	i++;
            continue;
        }
        console.log(i);
        i++;
    }
</script>

在这里插入图片描述

数组

JavaScript 中创建数组主要有两种方式:

  1. 使用 new 关键字创建
  2. 使用字面常量方式创建
<script>
    let arr1 = new Array(); //使用new关键字创建
    let arr2 = [] //使用字面常量创建
    let arr3 = [1,'你好'] //也可以在创建的时候就向数组中添加元素
</script>

JavaScript 中的数组中的元素不要求数据类型都相同

获取数组元素

获取数组中的元素可以直接通过数组名来获取数组中的全部元素,也可以通过数组名[下标]的方式访问某个特定的元素(数组下标从0开始)。

<script>
    let arr = ['张三','李四','王五','赵六',1,2,3]
    console.log(arr)
    console.log(arr[0])
    console.log(arr[1])
    console.log(arr[5])
</script>

在这里插入图片描述
如果访问的元素的下标超过了数组可以表示的范围,那么获取到的结果就是 undefined:

console.log(arr[10])

在这里插入图片描述
既然通过下标可以获取到数组中指定的元素,那么也就可以修改某个特定的元素:

<script>
    let arr = ['张三','李四','王五','赵六',1,2,3];
    console.log(arr);
    arr[1] = 100;
    console.log(arr)
</script>

在这里插入图片描述

新增数组元素

JavaScript 中新增数组元素的方式有三种:

  1. 修改 length 属性
  2. 通过下标新增
  3. 使用 push 进行追加元素
<script>
    let arr = [1,4,3,3]
    arr.length = 6
    console.log(arr[4])
    console.log(arr[5])
</script>

在这里插入图片描述
通过修改 length 属性来添加的元素的默认值是 undefined。

<script>
    let arr = []
    arr[1] = 10
    console.log(arr[0])
    console.log(arr[1])
</script>

在这里插入图片描述

<script>
    let arr = [1,2,3,4,5]
    arr.push(10)
    console.log(arr)
</script>

在这里插入图片描述

删除数组中的元素

JavaScript 中删除数组中的元素可以使用 splice 方法:arr.splice(index,n),index 表示从数组哪个元素开始删除,n 表示从 index 开始删除多少个元素。

<script>
    let arr = [1,2,3,4,5]
    arr.splice(1,3)
    console.log(arr)
</script>

在这里插入图片描述

函数

语法格式:

//创建函数/函数声明/函数定义
function 函数名(参数列表) {
	函数体
	return 返回值
}

//函数的调用
函数名(实参列表) //不考虑返回值
返回值 = 函数名(实参列表) //考虑返回值
<script>
    function sayHello() {
        console.log('hello');
    }
</script>

当我们定义完成函数之后,函数不会自动执行,只有函数被调用之后函数才会执行:

sayHello();

函数的定义和调用的先后顺序没有要求,这点不跟 python、c 等定义函数必须要调用函数之前。

对于参数个数
如果实参的个数多余形式参数的个数,那么形参会根据实参的顺序来进行初始化,多出来的实参不参与计算;如果实际参数的个数少于形式参数的个数的话,那么多出来的形式参数的值就是 undefined。

<script>
    function sum(a,b) {
        return a + b;
    }
    let ret = sum(10,20) //实参和形参的个数相同
    console.log(ret)
    ret = sum(10) //实参的个数少于形参的个数
    console.log(ret)
    ret = sum(10,20,30) //实参的个数多余形参的个数
    console.log(ret)
</script>

在这里插入图片描述
除了上面的定义函数的方式之外,还有一种定义函数的方式:

let 函数名 = function() {
	函数体
	return 返回值
}
<script>
    let sum = function(a,b) {
        return a + b;
    }
    let ret = sum(10,20);
    console.log(ret)
</script>

在这里插入图片描述

  • function(){} 这样的写法定义了一个匿名的函数,然后将这个匿名函数用一个变量来表示,后面就可以通过这个变量来调用函数了

变量在函数中的作用域

在 ES6 标准之前,作用域主要分为两个:

  • 全局作用域:在整个 script 标签中,或者单独的 .js 文件中生效
  • 局部作用域/函数作用域:在函数内部生效
<script>
    let num = 10; //全局变量,在整个script标签中都可以访问到
    function test() {
        console.log(num); 
    }
    test() //10
</script>
<script>
    function test() {
        let num = 10; //局部变量,该变量只有在test函数中才可以被访问到,出了这个函数之后就会被销毁
    }
    test();
    console.log(num);
</script>

在这里插入图片描述
创建变量的时候如果不写 let 或者 var 的话,那么该变量就是一个全局变量:

<script>
    function test() {
        num = 10;
    }
    test();
    console.log(num);
</script>

在这里插入图片描述

作用域链

如果在函数的外部和内部都存在,那么访问这个变量的时候访问的结果是什么呢?这就需要知道什么是变量的作用域链了:变量的查找是从内到外查找的,换句话说就是在该访问之间的代码中服从就近原则。

<script>
    let num = 10;
    function test() {
        let num = 20;
        console.log(num);
    }
    test();
</script>

在这里插入图片描述

对象

这里对象的概念是什么我就不给大家解释了,大家有兴趣可以自己去百度。

在 JavaScript 中如何创建对象呢?有三种方式:

  1. 使用字面量创建对象
  2. 使用 new Object 创建对象
  3. 使用构造函数创建对象

使用字面量创建对象
使用字面量创建对象的时候,对象内的属性和属性的值之间需要使用 : 分隔,并且属性声明的时候不能使用 let 或者 var,属性之间使用 , 分隔。

<script>
    let a = {} //创建一个空对象
    let student = {
        name: '张三',
        age: 18,
        sex: '男',
        sayHello: function() {
            console.log(this.name + '说:hello')
        }
    }
    console.log(student.name);
    console.log(student['age']);
    console.log(student.sex);
    student.sayHello();
</script>

在这里插入图片描述
在对象之内的函数中要想访问本对象的属性的时候需要使用 this.属性名 来访问。在对象之外访问对象中的属性或者函数的时候,可以使用 对象名.属性名/函数名 或者 对象名[’属性名‘] 来访问。

使用 new Object 创建对象

当使用 new Object 创建对象的时候,此时的对象还只是一个空对象,要想让对象具有属性或者方法,就需要使用 对象名.属性名/函数名 = ... 来为对象添加属性或者函数:

<script>
    let student = new Object();
    student.name = '张三';
    student.age = 18;
    student.sex = '男';
    student.sayHello = function() {
        console.log(student.name + '说:hello');
    }
    console.log(student.name);
    console.log(student['age']);
    console.log(student.sex);
    student.sayHello();
</script>

在这里插入图片描述

使用构造函数创建对象

上面的两种方式只能创建一个对象,而使用构造函数可以很方便的创建多个对象。

function 构造函数名(参数列表) {
	this.属性 = 值;
	this.方法 = function...
}

let obj = new 构造函数名(实参);
<script>
    function Cat(name,type,sound) {
        this.name = name;
        this.type = type;
        this.sound = function() {
            console.log(sound);
        }
    }
    let huahua = new Cat('花花','狸花猫','喵');
    let mimi = new Cat('咪咪','银渐层','喵喵');
    console.log(mimi);
    mimi.sound();
</script>

在这里插入图片描述

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不能再留遗憾了

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

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

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

打赏作者

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

抵扣说明:

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

余额充值