JavaScript基础内容

文章目录

JavaScript

JavaScript 是什么

JavaScript 是世界上最流行的语言之一,是一种运行在客户端的脚本语言 (Script 是脚本的意思),它不需要编译,运行过程中由 js 解释器( js 引擎)逐行来进行解释并执行。

JavaScript 的作用

  1. 表单动态校验(密码强度检测)
  2. 网页特效
  3. 服务端开发(Node.js)
  4. 桌面程序(Electron)
  5. App(Cordova)
  6. 控制硬件-物联网(Ruff)
  7. 游戏开发(cocos2d-js)

浏览器执行 JS 简介

浏览器分成两部分:渲染引擎和 JS 引擎

**渲染引擎:**用来解析HTML与CSS,俗称内核,比如 chrome 浏览器的 blink ,老版本的 webkit

JS 引擎:也称为 JS 解释器。 用来读取网页中的JavaScript代码,对其处理后运行,比如 chrome 浏览器的 V8

其实浏览器本身并不会执行JS代码,而是通过内置 JavaScript 引擎(解释器) 来执行 JS 代码 。JS 引擎执行代码时逐行解释
每一句源码(转换为机器语言),然后由计算机去执行,所以 JavaScript 语言归为脚本语言,会逐行解释执行。

JS 的组成

ECMAScript

ECMAScript 是由ECMA 国际( 原欧洲计算机制造商协会)进行标准化的一门编程语言,这种语言在万维网上应用广泛,它往往被称为 JavaScript 或 JScript,但实际上后两者是 ECMAScript 语言的实现和扩展。

DOM ——文档对象模型

文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的标准编程接口。
通过 DOM 提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)。

BOM ——浏览器对象模型

BOM (Browser Object Model,简称BOM) 是指浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等。

JS书写位置

行内

  • 可以将单行或少量 JS 代码写在HTML标签的事件属性中(以 on 开头的属性),如:onclick
  • 注意单双引号的使用:在HTML中我们推荐使用双引号, JS 中我们推荐使用单引号
  • 可读性差, 在html中编写JS大量代码时,不方便阅读;
  • 引号易错,引号多层嵌套匹配时,非常容易弄混;
  • 特殊情况下使用
内嵌

  • 可以将多行JS代码写到

- 利于HTML页面代码结构化,把大段 JS代码独立到 HTML 页面之外,既美观,也方便文件级别的复用
- 引用外部 JS文件的 script 标签中间不可以写代码
- 适合于JS 代码量比较大的情况



### JavaScript 注释

#### 单行注释

```javascript
// 我是一行文字
多行注释
/*
我是一行文字
*/

JavaScript 输入输出语句

为了方便信息的输入输出,JS中提供了一些输入输出语句,其常用的语句如下:

方法说明作用于
alert(msg)浏览器弹出警示框浏览器
console.log(msg)浏览器控制台打印输出信息浏览器
prompt(info)浏览器弹出输入框,用户可以输入浏览器

**注意:**alert() 主要用来显示消息给用户,console.log() 用来给程序员自己看运行时的消息。

变量

什么是变量

变量是用于存放数据的容器。 我们通过 变量名 获取数据,甚至数据可以修改,变量是程序在内存中申请的一块用来存放数据的空间。

变量的使用

变量在使用时分为两步: 1. 声明变量 2. 赋值

声明变量
// 声明变量
var age; // 声明一个 名称为age 的变量

var 是一个 JS关键字,用来声明变量( variable 变量的意思 )。使用该关键字声明变量后,计算机会自动为变量分配内存空间,而age 是程序员定义的变量名,我们要通过变量名来访问内存中分配的空间。

赋值
age = 10; // 给 age 这个变量赋值为 10
变量的初始化

声明一个变量并赋值, 我们称之为变量的初始化

var age = 18; // 声明变量同时赋值为 18
更新变量

一个变量被重新复赋值后,它原有的值就会被覆盖,变量值将以最后一次赋的值为准。

var age = 18;
age = 81; // 最后的结果就是81因为18 被覆盖掉了
同时声明多个变量

同时声明多个变量时,只需要写一个 var, 多个变量名之间使用英文逗号隔开。

var age = 10, name = 'zs', sex = 2;
声明变量特殊情况
情况说明输出结果
var age ; console.log (age);只声明 不赋值undefined
console.log(age)不声明 不赋值 直接使用报错
age = 10; console.log (age);不声明 只赋值10
变量命名规范
  • 由字母(A-Za-z)、数字(0-9)、下划线(_)、美元符号( $ )组成,如:usrAge, num01, _name
  • 严格区分大小写。var app; 和 var App; 是两个变量
  • 不能 以数字开头。 18age 是错误的
  • 不能 是关键字、保留字。例如:var、for、while
  • 变量名必须有意义。 MMD BBD nl → age
  • 遵守驼峰命名法。首字母小写,后面单词的首字母需要大写。 myFirstName

数据类型

数据类型简介

变量是用来存储值的所在处,它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的 内存中。JavaScript 是一种弱类型或者说动态语言。这意味着不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。

var age = 10; // 这是一个数字型
var areYouOk = '是的'; //

在代码运行时,变量的数据类型是由 JS引擎 根据 = 右边变量值的数据类型来判断 的,运行完毕之后, 变量就确定了数据类型。

JavaScript 拥有动态类型,同时也意味着相同的变量可用作不同的类型:

var x = 6; // x 为数字
var x = "Bill"; // x 为字符串 
为什么需要数据类型

在计算机中,不同的数据所需占用的存储空间是不同的,为了便于把数据分成所需内存大小不同的数据,充分利 用存储空间,于是定义了不同的数据类型。 简单来说,数据类型就是数据的类别型号。比如姓名“张三”,年龄18,这些数据的类型是不一样的。

数据类型的分类
  • 值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。
  • 引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。
数字型 Number

JavaScript 数字类型既可以用来保存整数值,也可以保存小数(浮点数)。

var age = 21; // 整数
var Age = 21.3747; // 小数 

不过,我们也可以数据进制型数据:

// 在JS中八进制前面加0,十六进制前面加 0x
// 八进制数字序列范围:0~7
var num1 = 07; // 对应十进制的7
var num2 = 019; // 对应十进制的19
var num3 = 08; // 对应十进制的8
 // 十六进制数字序列范围:0~9以及A~F
var num = 0xA;

我们也可以输入一个数字型范围:

/*
	JavaScript中数值的最大和最小值
	最大值:Number.MAX_VALUE,这个值为: 1.7976931348623157e+308
	最小值:Number.MIN_VALUE,这个值为:5e-32
*/
alert(Number.MAX_VALUE); // 1.7976931348623157e+308
alert(Number.MIN_VALUE); // 5e-324

此外,还有三个特殊值:

/*
Infinity ,代表无穷大,大于任何数值
-Infinity ,代表无穷小,小于任何数值
NaN ,Not a number,代表一个非数值
*/
alert(Infinity); // Infinity
alert(-Infinity); // -Infinity
alert(NaN); // NaN
isNaN()

isNaN()用来判断一个变量是否为非数字的类型,返回 true 或者 false

var usrAge = 21;
var isOk = isNaN(userAge);
console.log(isNum); // false ,21 不是一个非数字
var usrName = "andy";
console.log(isNaN(userName)); // true ,"andy"是一个非数字
字符串型 String

字符串型可以是引号中的任意文本,其语法为 双引号 “” 和 单引号’’

// 因为 HTML 标签里面的属性使用的是双引号,JS 这里我们更推荐使用单引号。
var strMsg = "我爱北京天安门~"; // 使用双引号表示字符串
var strMsg2 = '我爱吃猪蹄~'; // 使用单引号表示字符串
// 常见错误
var strMsg3 = 我爱大肘子; // 报错,没使用引号
字符串引号嵌套

JS 可以用单引号嵌套双引号 ,或者用双引号嵌套单引号 (外双内单,外单内双

var strMsg = '我是"高帅富"程序猿'; // 可以用''包含""
var strMsg2 = "我是'高帅富'程序猿"; // 也可以用"" 包含'' // 常见错误
var badQuotes = 'What on earth?"; // 报错,不能 单双引号搭
字符串转义符

类似HTML里面的特殊字符,字符串中也有特殊字符,我们称之为转义符。 转义符都是 \ 开头的,常用的转义符及其说明如下:

转义符解释说明
\n换行符,n 是 newline 的意思
\ \斜杠 \
’ 单引号
\””双引号
\ttab 缩进
\b空格 ,b 是 blank 的意思
字符串长度

字符串是由若干字符组成的,这些字符的数量就是字符串的长度。通过字符串的 length 属性可以获取整个字符 串的长度。

var strMsg = "我是帅气多金的程序猿!";
alert(strMsg.length); // 显示 11
字符串拼接

多个字符串之间可以使用 + 进行拼接,其拼接方式为 字符串 + 任何类型 = 拼接之后的新字符串, 拼接前会把与字符串相加的任何类型转成字符串,再拼接成一个新的字符串。

//1.1 字符串 "相加" alert('hello' + ' ' + 'world'); // hello world
//1.2 数值字符串 "相加" alert('100' + '100'); // 100100
//1.3 数值字符串 + 数值
alert('11' + 12); // 1112 

console.log('我' + 18); // 只要有字符就会相连
var age = 18;
// console.log('我age岁啦'); // 无法设置年龄,因为整体是个字符串
console.log('我' + age); // 我18
console.log('我' + age + '岁啦'); // 我18岁啦
布尔型 Boolea

布尔类型有两个值:true 和 false ,其中 true 表示真(对),而 false 表示假(错)。 布尔型和数字型相加的时候, true 的值为 1 ,false 的值为 0。

console.log(true + 1); // 2
console.log(false + 1); // 1
Undefined 和 Null

一个声明后没有被赋值的变量会有一个默认值 undefined ( 如果进行相连或者相加时,注意结果)

var variable;
console.log(variable); // undefined
console.log('你好' + variable); // 你好undefined
console.log(11 + variable); // NaN
console.log(true + variable); // Na

一个声明变量给 null 值,里面存的值为空

var vari = null;
console.log('你好' + vari); // 你好null
console.log(11 + vari); // 11
console.log(true + vari); // 1
获取变量数据类型

typeof 可用来获取检测变量的数据类型

var num = 18;
console.log(typeof num) // 结果 number

不同类型的返回值:

类型结果
Undefined"undefined"
Null"object"
Boolean"boolean"
Number"number"
BigInt(ECMAScript 2020 新增)"bigint"
String"string"
Symbol (ECMAScript 2015 新增)"symbol"
宿主对象(由 JS 环境提供)取决于具体实现
Function 对象 (按照 ECMA-262 规范实现 [[Call]])"function"
其他任何对象"object"
数据类型转换

类型转换可以分为两种:隐式类型转换显式类型转换

显式类型强制转换 是指当开发人员通过编写适当的代码用于在类型之间进行转换,比如:Number(value)。

隐式类型转换 是指在对不同类型的值使用运算符时,值可以在类型之间自动的转换,比如0 == null

需要注意的是:

  • NaN 的数据类型是 number
  • 数组(Array)的数据类型是 object
  • 日期(Date)的数据类型为 object
  • null 的数据类型是 object
  • 未定义变量的数据类型为 undefined

如果对象是 JavaScript Array 或 JavaScript Date ,我们就无法通过 typeof 来判断他们的类型,因为都是 返回 object。

在 JavaScript 中只有 3 种类型的转换:

**String 类型:**String() / toString()

**Number 类型:**Number() / parseFloat() / parseInt()

Boolean 类型: Boolean()

String 类型
方式说明示例
toString()转成字符串var num=1;console.log(num.toString());
String()强制转换转成字符串var num=1;console.log(String(num);
使用+拼接字符串该方式属于隐式转换,和字符串拼接的结果都是字符串var num=1;console.log(num + ‘字符串’);
转换为数字型
方式说明示例
parseInt(String)将String类型转换为整数数值类型parseInt(‘99’)
parseFloat(String)将String类型转换为浮点数数值类型parseFloat(‘99.99’)
Number()将String转换为数值型Number(‘99’)
隐式转换( - * /)利用算术运算隐式转换为数值型console.log(‘99’-0);

注意: Number()函数会将空字符串转换为 0,其他的字符串会转换为 NaN (不是个数字)。

转换为布尔型
方式说明示例
Boolean()将其他类型转换为布尔型Boolean(true)

PS:

  • 代表否定的值会被转换为 false ,如 ‘’、0、NaN、null、undefined
  • 其余值都会被转换为 true

示例:

console.log(Boolean('')); // false
console.log(Boolean(0)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean('小白')); // true
console.log(Boolean(12)); // true

运算符

运算符(operator)也被称为操作符,是用于实现赋值、比较和执行算数运算等功能的符号。

JavaScript常用运算符
  • 算数运算符
  • 递增和递减运算符
  • 比较运算符
  • 逻辑运算符
  • 赋值运算符
算数运算符

算术运算使用的符号,用于执行两个变量或值的算术运算。

运算符说明示例
+1 + 1
-1 - 1
*1 * 1
/1 / 1
%取余9 % 2 = 1
浮点数的精度问题

浮点数值的最高精度是 17 位小数,但在进行算术计算时其精确度远远不如整数。所以:不要直接判断两个浮点数是否相等 。

var result = 0.1 + 0.2;    // 结果不是 0.3,而是:0.30000000000000004
console.log(0.07 * 100);   // 结果不是 7,  而是:7.000000000000001
递增和递减运算符

如果需要反复给数字变量添加或减去1,可以使用递增(++)和递减( --)运算符来完成。

在 JavaScript 中,递增(++)和递减( – )既可以放在变量前面,也可以放在变量后面。放在变量前面时,我们可以称为前置递增(递减)运算符,放在变量后面时,我们可以称为后置递增(递减)运算符。

**注意:**递增和递减运算符必须和变量配合使用。

前置递增运算符

++num 前置递增,就是自加1,类似于 num = num + 1,它是先自加,后返回值。

var num = 10;
alert(++num + 10); // 21
后置递增运算符

num++ 后置递增,就是自加1,类似于 num = num + 1 ,它是先返回原值,后自加。

var num = 10;
alert(10 + num++); // 20
比较运算符

比较运算符(关系运算符)是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值 (true / false)作为比较运算的结果。

运算符名称说明示例结果
<小于1 < 2true
>大于1 > 2false
<=小于等于2 <= 2true
>=大于等于3 >= 2true
==判断(会转型)1 == 1true
!=不等于1 != 1false
=== !==全等,要求数据与类型都一致1 === ‘1’false
逻辑运算符

逻辑运算符是用来进行布尔值运算的运算符,其返回值也是布尔值。

运算符说明示例
&&逻辑与,简称与 andtrue && false
||逻辑或,简称或 ortrue || false
!逻辑非,简称非 not! true
赋值运算符
运算符说明示例
=直接赋值var num = 1
+=、-=加、减一个数后再赋值var num =10;num += 5
*=、/=、%=乘、除、取模后再赋值var num =10;num *= 5

示例:

var age = 10;
age += 5; // 相当于 age = age + 5;
age -= 5; // 相当于 age = age - 5;
age *= 10; // 相当于 age = age * 10;
运算符优先级

下面的表格将所有运算符按照优先级的不同从高(19)到低(1)排列。

运算符优先级

流程控制

在一个程序执行的过程中,各条代码的执行顺序对程序的结果是有直接影响的。很多时候我们要通过控制代码 的执行顺序来实现我们要完成的功能。 流程控制主要有三种结构,分别是顺序结构分支结构循环结构,这三种结构代表三种代码执行的顺序。

程控制

顺序流程控制

顺序结构是程序中最简单、最基本的流程控制,它没有特定的语法结构,程序会按照代码的先后顺序,依次执行。

分支流程控制

由上到下执行代码的过程中,根据不同的条件,执行不同的路径代码(执行代码多选一的过程),从而得到不同的结果,JS 语言提供了两种分支结构语句:if 语句switch 语句

if 语句

语法结构

// 条件成立执行代码,否则什么也不做
if (条件表达式) {
	// 条件成立执行的代码语句
}
if else语句(双分支语句)

语法结构

// 条件成立 执行 if 里面代码,否则执行else 里面的代码
if (条件表达式) {
	// [如果] 条件成立执行的代码
} else {
	// [否则] 执行的代码
}
if else if 语句(多分支语句)

语法结构

// 适合于检查多重条件。
if (条件表达式1) {
	语句1} else if (条件表达式2) {
	语句2} else if (条件表达式3) {
	语句3....
} else {
// 上述条件都不成立执行此处代码
}
三元表达式

三元表达式也能做一些简单的条件选择。 有三元运算符组成的式子称为三元表达式。

**语法结构:**表达式1 ? 表达式2 : 表达式3;

执行过程:如果表达式1为 true ,则返回表达式2的值,如果表达式1为 false,则返回表达式3的值。

switch 语句

switch 语句也是多分支语句,它用于基于不同的条件来执行不同的代码。当要针对变量设置一系列的特定值 的选项时,就可以使用 switch。

switch( 表达式 ){ 
	case value1:
		// 表达式 等于 value1 时要执行的代码
		break;
	case value2:
		// 表达式 等于 value2 时要执行的代码
		break;
	default:
	// 表达式 不等于任何一个 value 时要执行的代码
}
switch 语句和 if else if 语句的区别
  1. 一般情况下,它们两个语句可以相互替换
  2. switch…case 语句通常处理 case为比较确定值的情况, 而 if…else…语句更加灵活,常用于范围判断(大于、等 于某个范围)
  3. switch 语句进行条件判断后直接执行到程序的条件语句,效率更高。而if…else 语句有几种条件,就得判断多 少次。
  4. 当分支比较少时,if… else语句的执行效率比 switch语句高。
  5. 当分支比较多时,switch语句的执行效率比较高,而且结构更清晰。

循环

在实际问题中,有许多具有规律性的重复操作,因此在程序中要完成这类操作就需要重复执行某些语句

在Js 中,主要有三种类型的循环语句:

  • for 循环
  • while 循环
  • do…while 循环
for 循环

在程序中,一组被重复执行的语句被称之为循环体,能否继续重复执行,取决于循环的终止条件。由循环体 及循环的终止条件组成的语句,被称之为循环语句

for 循环主要用于把某些代码循环若干次,通常跟计数有关系。其语法结构如下:

for(初始化变量; 条件表达式; 操作表达式 ){
	//循环体
}
  • **初始化变量:**通常被用于初始化一个计数器,该表达式可以使用 var 关键字声明新的变量,这个变量帮我们来记录次数。
  • 条件表达式:用于确定每一次循环是否能被执行。如果结果是 true 就继续循环,否则退出循环。
  • **操作表达式:**每次循环的最后都要执行的表达式。通常被用于更新或者递增计数器变量。当然,递减变量也是可以的。
执行过程:
  1. 初始化变量,初始化操作在整个 for 循环只会执行一次。
  2. 执行条件表达式,如果为true,则执行循环体语句,否则退出循环,循环结束。
  3. 执行操作表达式,此时第一轮结束。
  4. 第二轮开始,直接去执行条件表达式(不再初始化变量),如果为 true ,则去执行循环体语句,否则退出循环。
  5. 继续执行操作表达式,第二轮结束。
  6. 后续跟第二轮一致,直至条件表达式为假,结束整个 for 循环。
while 循环

while 语句可以在条件表达式为真的前提下,循环执行指定的一段代码,直到表达式不为真时结束循环。 while语句的语法结构如下:

while (条件表达式) {
	// 循环体代码
}

执行过程:

  1. 先执行条件表达式,如果结果为 true,则执行循环体代码;如果为 false,则退出循环,执行后面代码
  2. 执行循环体代码
  3. 循环体代码执行完毕后,程序会继续判断执行条件表达式,如条件仍为true,则会继续执行循环体,直到循 环条件为 false 时,整个循环过程才会结束
do while 循环

do… while 语句其实是 while 语句的一个变体。该循环会先执行一次代码块,然后对条件表达式进行判断,如 果条件为真,就会重复执行循环体,否则退出循环。

do {
// 循环体代码 - 条件表达式为 true 时重复执行循环体代码
} while(条件表达式);

执行思路:

  1. 先执行一次循环体代码
  2. 再执行条件表达式,如果结果为 true,则继续执行循环体代码,如果为 false,则退出循环,继续执行后面 代码
continue break
continue 关键字

continue 关键字用于立即跳出本次循环,继续下一次循环(本次循环体中 continue 之后的代码就会少执行一 次)

    for (var i = 1; i <= 5; i++) {
        if (i == 3) {
            console.log('跳出循环...');
            continue; // 跳出本次循环,跳出的是第3次循环
        }
        console.log('正在执行第' + i + '次循环');
    }
break 关键字

break 关键字用于立即跳出整个循环(循环结束)。

 for (var i = 1; i <= 5; i++) {
        if (i == 3) {
            console.log('退出循环...');
            break; // 立即跳出整个循环
        }
        console.log('正在执行第' + i + '次循环');
    }

命名规范

标识符命名规范
  • 变量、函数的命名必须要有意义
  • 变量的名称一般用名词
  • 函数的名称一般用动词
操作符规范
    // 操作符的左右两侧各保留一个空格
    for (var i = 1; i <= 5; i++) {
        if (i == 3) {
            console.log('跳出循环...');
            continue; // 跳出本次循环,跳出的是第3次循环
        }
        console.log('正在执行第' + i + '次循环');
    }
单行注释规范
 // 单行注释前面注意有个空格
    for (var i = 1; i <= 5; i++) {
        if (i == 3) {
            console.log('跳出循环...');
            continue; // 跳出本次循环,跳出的是第3次循环
        }
        console.log('正在执行第' + i + '次循环');
    }

数组

数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。数组是一种将一组数据存储在单个变量名下的优雅方式。

    // 普通变量一次只能存储一个值
    var num = 10;
    // 数组一次可以存储多个值
    var arr = [1, 2, 3, 4, 5];
创建数组
new 创建数组
var 数组名 = new Array()var arr = new Array(); // 创建一个新的空数组
数组字面量创建数组
//1. 使用数组字面量方式创建空的数组
var 数组名 = []//2. 使用数组字面量方式创建带初始值的数组
var 数组名 = ['小白','小黑','大黄','瑞奇'];
数组元素的类型

数组中可以存放任意类型的数据,例如字符串,数字,布尔值等。

var arrStus = ['小白',12,true,28.9];
获取数组中的元素

**索引 (下标) :**用来访问数组元素的序号(数组下标从 0 开始),数组可以通过索引来访问、设置、修改对应的数组元素,我们可以通过“数组名[索引]”的形式来获取数组中的元素。

// 定义数组
var arrStus = [1,2,3];
// 获取数组中的第2个元素
alert(arrStus[1]);
数组的长度

使用“数组名.length”可以访问数组元素的数量(数组长度)。

var arrStus = [1,2,3];
alert(arrStus.length); // 3
数组中新增元素
通过修改 length 长度新增数组元素

可以通过修改 length 长度来实现数组扩容的目的 ,length 属性是可读写的

var arr = ['red', 'green', 'blue', 'pink'];
arr.length = 7;
console.log(arr);
// 其中索引号是 4,5,6 的空间没有给值,就是声明变量未给值,默认值就是 undefined。
console.log(arr[4]);
console.log(arr[5]);
console.log(arr[6]);
通过修改数组索引新增数组元素

可以通过修改数组索引的方式追加数组元素

var arr = ['red', 'green', 'blue', 'pink'];
arr[4] = 'hotpink';
console.log(arr);

JavaScript 函数

函数的概念

在 JS 里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量重复使用。 虽然 for循环语句也能实现一些简单的重复操作,但是比较具有局限性,此时我们就可以使用 JS 中的函数。

**函数:**就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量代码的重复使用。

函数的使用

函数在使用时分为两步:声明函数调用函数

声明函数
// 声明函数
function 函数名() {
	//函数体代码
}
  • function 是声明函数的关键字,必须小写
  • 由于函数一般是为了实现某个功能才定义的, 所以通常我们将函数名命名为动词,比如 getSum
调用函数
// 调用函数,且调用的时候千万不要忘记添加小括号
函数名(); // 通过调用函数名来执行函数体代码

**注意:**声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。

函数的封装

函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口,封装类似于将电脑配件整合组装到机箱中 ( 类似快递打包)。

    /* 
  计算1-100之间值的函数
  */
    // 声明函数
    function getSum() {
        var sumNum = 0;// 准备一个变量,保存数字和
        for (var i = 1; i <= 100; i++) {
            sumNum += i;// 把每个数值 都累加 到变量中
        }
        alert(sumNum);
    }
    // 调用函数
    getSum();
函数的参数

在声明函数时,可以在函数名称后面的小括号中添加一些参数,这些参数被称为形参,而在调用该函数时, 同样也需要传递相应的参数,这些参数被称为实参

参数说名
形参形式上的参数,函数定义的时候传递的参数,当前并不知道是什么
实参实际上的参数,函数调用的时候传递的参数,实参是传递给形参的

参数的作用 : 在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去。

// 带参数的函数声明
function 函数名(形参1, 形参2 , 形参3...) { // 可以定义任意多的参数,用逗号分隔
	// 函数体
}
// 带参数的函数调用
函数名(实参1, 实参2, 实参3...); 

示例:

// 利用函数求任意两个数的和
function getSum(num1, num2) {
    console.log(num1 + num2);
}
getSum(1, 3); // 4
getSum(6, 5); // 11
函数形参和实参个数不匹配问题
参数个数说明
实参个数等于形参个数结果正常
实参个数多余形参个数只取到形参的个数,多余的将会被忽略
实参个数小余形参个数多的形参定义为undefined

栗子:

function sum(num1, num2) {
    console.log(num1 + num2);
}
sum(100, 200); // 形参和实参个数相等,输出正确结果
sum(100, 400, 500, 700); // 实参个数多于形参,只取到形参的个数
sum(200); // 实参个数少于形参,多的形参定义为undefined,结果为NaN

**注意:**在JavaScript中,形参的默认值是undefined。

函数的返回值

有的时候,我们会希望函数将值返回给调用者,此时通过使用 return 语句就可以实现:

// 声明函数
function 函数名(){
	...
	return 需要返回的值;
}
// 调用函数
函数名(); // 此时调用函数就可以得到函数体内return 后面的值

注意:

  • 在使用 return 语句时,函数会停止执行,并返回指定的值
  • 如果函数没有 return ,返回的值是 undefined
  • return 只能返回一个值。如果用逗号隔开多个值,以最后一个为准。
return 终止函数

return 语句之后的代码不被执行:

function add(num1,num2){
//函数体
	return num1 + num2; // 注意:return 后的代码不执行
	alert('我不会被执行,因为前面有 return');
}
var resNum = add(21,6); // 调用函数,传入两个实参,并通过 resNum 接收函数返回值
alert(resNum); // 27
break ,continue ,return 的区别
  • break :结束当前的循环体(如 for、while)
  • continue :跳出本次循环,继续执行下次循环(如 for、while)
  • return :不仅可以退出循环,还能够返回 return 语句中的值,同时还可以结束当前的函数体内的代码
arguments

当我们不确定有多少个参数传递的时候,可以用 arguments 来获取。在 JavaScript 中,arguments 实际上它 是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象,arguments 对象中存储了传递的所有 实参

arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:

  • 具有 length 属性
  • 按索引方式储存数据
  • 不具有数组的 push , pop 等方法
arguments的使用
// 任意个数的最大值
function maxValue() {
    var max = arguments[0];
    for (var i = 0; i < arguments.length; i++) {
        if (max < arguments[i]) {
            max = arguments[i];
        }
    }
    return max;
}
console.log(maxValue(2, 4, 5, 9));
console.log(maxValue(12, 4, 9));
函数的两种声明方式
自定义函数方式(命名函数)
  • 因为有名字,所以也被称为命名函数
  • 调用函数的代码既可以放到声明函数的前面,也可以放在声明函数的后面

示例:

// 声明定义方式
function fn() {...}
	// 调用
fn();
函数表达式方式(匿名函数)
  • 因为函数没有名字,所以也被称为匿名函数
  • 这个fn 里面存储的是一个函数
  • 函数表达式方式原理跟声明变量方式是一致的
  • 函数调用的代码必须写到函数体后面
// 这是函数表达式写法,匿名函数后面跟分号结束
var fn = function(){...}// 调用的方式,函数调用必须写到函数体下面
fn();

作用域

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这 个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

JavaScript(es6前)中的作用域有两种:

  1. 全局作用域
  2. 局部作用域(函数作用域)
全局作用域

作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件。

局部作用域 (函数作用域)

作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域。

块级作用域

块作用域由 { } 包裹,在其他编程语言中(如 java、c#等),在 if 语句、循环语句中创建的变量,仅仅只能在本 if 语句、本循 环语句中使用,如下面的Java代码:

if(true){
	int num = 123;
	system.out.print(num); // 123
}
system.out.print(num); // 报错

但Js中没有块级作用域(在ES6之前)的,例如:

if(true){
	var num = 123;
	console.log(123); //123
}
console.log(123); //123
变量的作用域

在中,根据作用域的不同,变量可以分为两种:

  1. 全局变量
  2. 局部变量
全局变量

在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。

  • 全局变量在代码的任何位置都可以使用
  • 在全局作用域下 var 声明的变量 是全局变量
  • 特殊情况下,在函数内不使用 var 声明的变量也是全局变量(不建议使用)
局部变量

在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)

  • 局部变量只能在该函数内部使用
  • 在函数内部 var 声明的变量是局部变量
  • 函数的形参实际上就是局部变量
全局变量和局部变量的区别
  • 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
  • 局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被 销毁,因此更节省内存空间
作用域链

在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

作用域链决定了哪些数据能被函数访问。当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。

说直白一点就是 作用域的集合就是作用域链(子集可以访问父集,父集不能访问子集)

function fn(){
    var a=10;
    function fn1(){
        var b=20;
        alert(a) //10
        function fn2(){
            alert(b) //20
            alert(a) //10  子集可以跨级访问父级
        }
        fn2()
    }
    fn1()
}
fn()
alert(b) // 报错

上面这个案例就说明了作用域链的概念,它就是作用域的集合组合起来的一个东西

从作用域链的结构可以看出,函数在执行的过程中,先从自己内部寻找变量,如果找不到,再从创建当前函数所在的作用域去找,从此往上,也就是向上一级找,直到找到全局作用域还是没找到。

作用域链代码优化

在运行期上下文的作用域链中,标识符所在的位置越深,读写速度就会越慢。如上面案例所示,因为全局变量总是存在于运行期上下文作用域链的最末端,因此在标识符解析的时候,查找全局变量是最慢的。

所以,在编写代码的时候应尽量少使用全局变量,尽可能使用局部变量。

执行顺序

当在作用域内访问 变量/方法 的时候,会找离自己最近的那个 变量/方法 (就近原则)

var a=10;
function fn(){
    var a=20;
    console.log(a) //20
}
fn()
总结

1、函数在执行的过程中,先从自己内部寻找变量
2、如果找不到,再从创建当前函数所在的作用域去找,从此往上,也就是向上一级找。
当在作用域内访问 变量/方法 的时候,会找离自己最近的那个 变量/方法 (就近原则)

预解析

JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时 候分为两步:预解析和代码执行。

**预解析:**在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明的变量在内存中 进行提前声明或者定义。

代码执行: 从上到下执行JS语句。

变量预解析(变量提升)

预解析也叫做变量、函数提升。

变量提升: 变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升

函数预解析(函数提升)

函数提升: 函数的声明会被提升到当前作用域的最上面,但是不会调用函数。

需要注意的是:函数表达式在调用的时候必须写在的下面

// 正确的例子
var fun = function fn(){
    // var fun = function fn() 这种方式被称为函数表达式。
}
fn();

// 错误的例子
fn();
var fun = function fn(){
    // var fun = function fn() 这种方式被称为函数表达式。
}

对象

现实生活中:万物皆对象,对象是一个具体的事物,看得见摸得着的实物。例如,一本书、一辆汽车、一个人 可以是“对象”,一个数据库、一张网页、一个与远程服务器的连接也可以是“对象”

在 JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、 函数等。

对象是由属性方法组成的。

  • 属性:事物的特征,在对象中用属性来表示(常用名词)
  • 方法:事物的行为,在对象中用方法来表示(常用动词)
创建对象的三种方式
  1. 利用字面量创建对象
  2. 利用 new Object 创建对象
  3. 利用构造函数创建对象
利用字面量创建对象

对象字面量:就是花括号 { } 里面包含了表达这个具体事物(对象)的属性和方法。 { } 里面采取键值对的形式表示

  • 键:相当于属性名
  • 值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等)
var star = {
    name: 'pink',
    age: 18,
    sex: '男',
    sayHi: function () {
        alert('大家好啊~');
    }
};
利用new Object创建对象
var andy = new Obect();
	andy.name = 'zhangsan';
	andy.age = 18;
	andy.sex = '男';
	andy.sayHi = function(){
    alert('大家好啊~');
}

注意:

  • Object() :第一个字母大写
  • new Object() :需要 new 关键字
  • 使用的格式:对象.属性 = 值
利用构造函数创建对象

**构造函数 :**是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起 使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

在 js 中,使用构造函数要时要注意以下两点:

  • 构造函数用于创建某一类对象,其首字母要大写
  • 构造函数要和 new 一起使用才有意义

示例:

    function Person(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.sayHi = function () {
            alert('我的名字叫:' + this.name + ',年龄:' + this.age + ',性别:' + this.sex);
        }
    }
    var bigbai = new Person('大白', 100, '男');
    var smallbai = new Person('小白', 21, '男');
    console.log(bigbai.name);
    console.log(smallbai.name);

注意:

  1. 构造函数约定首字母大写。
  2. 函数内的属性和方法前面需要添加 this ,表示当前对象的属性和方法。
  3. 构造函数中不需要 return 返回结果。
  4. 当我们创建对象的时候,必须用 new 来调用构造函数。
构造函数和对象的区别:
  • 构造函数,如 Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class)
  • 创建对象,如 new Stars(),特指某一个,通过 new 关键字创建对象的过程我们也称为对象实例化
对象的调用
  • 对象里面的属性调用 : 对象.属性名 ,这个小点 . 就理解为“ 的 ”
  • 对象里面属性的另一种调用方式 : 对象[‘属性名’],注意方括号里面的属性必须加引号,我们后面会用
  • 对象里面的方法调用:对象.方法名() ,注意这个方法名字后面一定加括号
console.log(star.name) // 调用名字属性
console.log(star['name']) // 调用名字属性
star.sayHi(); // 调用 sayHi 方法,注意,一定不要忘记带后面的括号
变量、属性、函数、方法总结

**变量:**单独声明赋值,单独存在

**属性:**对象里面的变量称为属性,不需要声明,用来描述该对象的特征

**函数:**单独存在的,通过“函数名()”的方式就可以调用

**方法:**对象里面的函数称为方法,方法不需要声明,使用“对象.方法名()”的方式就可以调用,方法用来描述该对象的 行为和功能。

new关键字

new 在执行时会做四件事情:

  1. 在内存中创建一个新的空对象。
  2. 让 this 指向这个新的对象。
  3. 执行构造函数里面的代码,给这个新对象添加属性和方法。
  4. 返回这个新对象(所以构造函数里面不需要return)
遍历对象属性

for…in 语句用于对数组或者对象的属性进行循环操作。 其语法如下:

for (变量 in 对象名字) {
	// 在此执行代码
}

语法中的变量是自定义的,它需要符合命名规范,通常我们会将这个变量写为 k 或者 key。

for (var k in obj) {
	console.log(k); // 这里的 k 是属性名
	console.log(obj[k]); // 这里的 obj[k] 是属性值
}

JavaScript 内置对象

JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象。内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)其优点就是帮助我们快速开发 ,JavaScript 提供了多个内置对象:Math、 Date 、Array、String等。

Math对象

Math 对象不是构造函数,它具有数学常数和函数的属性和方法。跟数学相关的运算(求绝对值,取整、最大值 等)可以使用 Math 中的成员。

常用方法:

Math.PI // 圆周率
Math.floor() // 向下取整
Math.ceil() // 向上取整
Math.round() // 四舍五入版 就近取整 注意 -3.5 结果是 -3 
Math.abs() // 绝对值
Math.max()/Math.min() // 求最大和最小值

随机数方法 random()

random() 方法可以随机返回一个小数,其取值范围是 [0,1),左闭右开 0 <= x < 1

// 得到一个两数之间的随机整数,包括两个数在内
//参考: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/random
function getRandom(min, max) {
	return Math.floor(Math.random() * (max - min + 1)) + min; 
}
日期对象

Date 对象和 Math 对象不一样,他是一个构造函数,所以我们需要实例化后才能使用,Date 实例用来处理日期和时间。

Date()方法的使用
// 获取当前时间必须实例化
var now = new Date();
console.log(now); // 
Date() 构造函数的参数

如果括号里面有时间,就返回参数里面的时间。例如日期格式字符串为‘2019-5-1’,可以写成new Date(‘2019-5-1’) 或者 new Date(‘2019/5/1’)。

如果Date()不写参数,就返回当前时间,如果Date()里面写参数,就返回括号里面输入的时间。

日期格式化
方法描述
getDate()返回月中的第几天(从 1 到 31)。
getDay()返回星期几(0-6)。
getFullYear()返回年份。
getHours()返回小时(从 0-23)。
getMilliseconds()返回毫秒(0-999)。
getMinutes()返回分钟(从 0-59)。
getMonth()返回月份(从 0-11)。
getSeconds()返回秒数(从 0-59)。
getTime()返回自 1970 年 1 月 1 日午夜以来与指定日期的毫秒数。
getTimezoneOffset()返回 UTC 时间与本地时间之间的时差,以分钟为单位。
getUTCDate()根据世界时,返回月份中的第几天(从 1 到 31)。
getUTCDay()根据世界时,返回星期几(0-6)。
getUTCFullYear()根据世界时,返回年份。
getUTCHours()根据世界时,返回小时(0-23)。
getUTCMilliseconds()根据世界时,返回毫秒数(0-999)。
getUTCMinutes()根据世界时,返回分钟(0-59)。
getUTCMonth()根据世界时,返回月份(0-11)。
getUTCSeconds()根据世界时,返回秒数(0-59)。
getYear()已弃用。请改用 getFullYear() 方法
now()]返回自 1970 年 1 月 1 日午夜以来的毫秒数。
parse()解析日期字符串并返回自 1970 年 1 月 1 日以来的毫秒数。
setDate()设置 Date 对象中月的某一天。
setFullYear()设置日期对象的年份
setHours()设置日期对象的小时。
setMilliseconds()设置日期对象的毫秒数。
setMinutes()设置日期对象的分钟数。
setMonth()设置日期对象的月份。
setSeconds()设置日期对象的秒数。
setTime()将日期设置为 1970 年 1 月 1 日之后/之前的指定毫秒数。
setUTCDate()根据世界时,设置 Date 对象中月份的一天。
setUTCFullYear()根据世界时,设置日期对象的年份。
setUTCHours()根据世界时,设置日期对象的小时。
setUTCMilliseconds()根据世界时,设置日期对象的毫秒数。
setUTCMinutes()根据世界时,设置日期对象的分钟数。
setUTCMonth()根据世界时,设置日期对象的月份。
setUTCSeconds()根据世界时,设置日期对象的秒数。
setYear()已弃用。请改用 setFullYear() 方法
toDateString()将 Date 对象的日期部分转换为可读字符串。
toGMTString()已弃用。请改用 toUTCString() 方法
toISOString()使用 ISO 标准将日期作为字符串返回。
toJSON()以字符串形式返回日期,格式为 JSON 日期。
toLocaleDateString()使用区域设置约定将 Date 对象的日期部分作为字符串返回。
toLocaleTimeString()使用区域设置约定将 Date 对象的时间部分作为字符串返回。
toLocaleString()使用区域设置约定将 Date 对象转换为字符串。
toString()将 Date 对象转换为字符串。
toTimeString()将 Date 对象的时间部分转换为字符串。
toUTCString()根据世界时,将 Date 对象转换为字符串。
UTC()根据 UTC 时间,返回自 1970 年 1 月 1 日午夜以来的日期中的毫秒数。
valueOf()返回 Date 对象的原始值。
创建一个日期对象的多种方法
var today = new Date();
var birthday = new Date('December 17, 1995 03:24:00');
var birthday = new Date('1995-12-17T03:24:00');
var birthday = new Date(1995, 11, 17);
var birthday = new Date(1995, 11, 17, 3, 24, 0);
数组对象
检测是否为数组
  • instanceof 运算符,可以判断一个对象是否属于某种类型
  • Array.isArray()用于判断一个对象是否为数组,isArray() 是 HTML5 中提供的方法
var arr = [1, 23];
var obj = {};
console.log(arr instanceof Array); // true
console.log(obj instanceof Array); // false
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false
添加删除数组元素的方法
方法名说明返回值
push(element1, …, elementN)向数组末尾添加一个或多个元素返回新的长度
pop()删除数组最后一个元素返回被删除元素的值
unshift(element1, …, elementN)将一个或多个元素添加到数组的开头返回新的长度
shift()删除数组的第一个元素返回被删除元素的值
数组排序
方法名说明是否修改原数组
reverse()颠倒数组中元素的顺序,无参数会改变原来的数组,并返回新数组
sort()对数组的元素进行排序会改变原来的数组,并返回新数组

示例:

function compare(a, b) {
  if (a < b ) {           // 按某种排序标准进行比较,a 小于 b
    return -1;
  }
  if (a > b ) {
    return 1;
  }
  // a must be equal to b
  return 0;
}
数组索引方法
方法名说明返回值
indexOf(searchElement[, fromIndex])数组中查找给定元素的第一个元素如果存在返回索引号,如果不存在,则返回-1
lastIndexOf(searchElement[, fromIndex])在数组中的最后一个索引如果存在返回索引号,如果不存在,则返回-1

参数:

**searchElement:**要查找的元素

**fromIndex:**可选参数,开始查找的位置。如果该索引值大于或等于数组长度,意味着不会在数组里查找,返回 -1。如果参数中提供的索引值是一个负值,则将其作为数组末尾的一个抵消,即 -1 表示从最后一个元素开始查找,-2 表示从倒数第二个元素开始查找 ,以此类推。 注意:如果参数中提供的索引值是一个负值,并不改变其查找顺序,查找顺序仍然是从前向后查询数组。如果抵消后的索引值仍小于 0,则整个数组都将会被查询。其默认值为 0。

数组转换为字符串
方法名说明返回值
toString()把数组转换成字符串,逗号分隔每一项字符串
join(‘分隔符’)所有的数组元素被转换成字符串,再用一个分隔符将这些字符串连接起来。字符串
数组的其他方法
方法名说明返回值
concat()并两个或多个数组。此方法不会更改现有数组新数组
slice()数组截取,slice(begin,end)新数组
splice()数组删除,splice(开始位置,删除个数)新数组,但会影响原数组
字符串对象
基本包装类型

为了方便操作基本数据类型,JavaScript 还提供了三个特殊的引用类型:String、Number和 Boolean。

基本包装类型就是把简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法。

// 下面代码有什么问题?
var str = 'andy';
console.log(str.length);

按道理基本数据类型是没有属性和方法的,而对象才有属性和方法,但上面代码却可以执行,这是因为 js 会 把基本数据类型包装为复杂数据类型,其执行过程如下 :

// 1. 生成临时变量,把简单类型包装为复杂数据类型
var temp = new String('andy');
// 2. 赋值给我们声明的字符变量
str = temp;
// 3. 销毁临时变量
temp = null;
字符串的不可变

字符串的不可变指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。

var str = 'abc';
str = 'hello';
// 当重新给 str 赋值的时候,常量'abc'不会被修改,依然在内存中
// 重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变
// 由于字符串的不可变,在大量拼接字符串的时候会有效率问题
var str = '';
for (var i = 0; i < 100000; i++) {
str += i;
}
console.log(str); // 这个结果需要花费大量时间来显示,因为需要不断的开辟新的空间
根据字符返回位置
方法名说明
indexOf(‘要查找的字符串’,开始的位置)返回指定内容在元字符串中的位置,如果找不到就返回-1,开始的位置是index索引号
lastIndexOf()从后往前找,只找到第一个匹配的
根据位置返回字符
方法名说明示例
charAt(index)返回指定位置的字符(index字符串的索引号)str.charAt(0)
charCodeAt(index)获取指定位置处字符的ASCII码(index索引号)str.charCodeAt(0)
srt(index)获取指定位置处字符str.srt(0)
字符串操作方法
方法名说明示例
charAt(index)返回指定位置的字符(index字符串的索引号)str.charAt(0)
charCodeAt(index)获取指定位置处字符的ASCII码(index索引号)str.charCodeAt(0)
concat(str1,str2…strn)连接多个字符串,相当于拼接字符串
substr(start[, length])返回一个字符串中从指定位置开始到指定字符数的字符。
slice(start,end)从开始位置,截取到end位置
substring(start,end)从开始位置,截取到end位置
replace(被替换的字符串, 要替换为的字符串)用于在字符串中用一些字符替换另一些字符
split()split()方法用于切分字符串,它可以将字符串切分为数组。str.split(‘,’)
toUpperCase()转换大写
toLowerCase()转换小写

简单类型与复杂类型

简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。

**值类型:**简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型 string ,number,boolean,undefined,null

**引用类型:**复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型 通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等

堆和栈

堆栈空间分配区别:

**栈(操作系统):**由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈; 简单数据类型存放到栈里面

**堆(操作系统):**存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。 复杂数据类型存放到堆里面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值