零基础学习JS--基础篇--索引集合类
数组是由名称和索引引用的值构成的有序列表。
JavaScript 中没有明确的数组数据类型。但是,你可以使用预定义的 Array
对象及其方法来处理应用程序中的数组。Array
对象具有以各种方式操作数组的方法,例如连接、反转和排序。它有一个用于确定数组长度的属性和用于正则表达式的其他属性。
创建数组
以下语句创建了等效的数组:
const arr1 = new Array(element0, element1, /* … ,*/ elementN);
const arr2 = Array(element0, element1, /* … ,*/ elementN);
const arr3 = [element0, element1, /* … ,*/ elementN];
element0, element1, …, elementN
是数组元素的值列表。当指定这些值时,数组将用它们作为数组的元素初始化。数组的 length
属性被设置为参数的数量。
括号语法称为“数组字面量”或“数组初始化式”。
为了创建一个长度不为 0,但是又没有任何元素的数组,可选以下任何一种方式:
// 这种方式...
const arr1 = new Array(arrayLength);// ...与这种方式会形成相同数组
const arr2 = Array(arrayLength);// 这个效果也一样
const arr3 = [];
arr3.length = arrayLength;
备注: 以上代码,arrayLength
必须为一个 Number
。否则,将会创建一个只有单个元素(内含提供的值)的数组。调用 arr.length
会返回 arrayLength
,但数组不包含任何元素。for...in 循环在数组上找不到任何属性。
如果你希望用单个元素初始化一个数组,而这个元素恰好又是 Number
,那么你必须使用括号语法。当单个 Number
传递给 Array()
构造函数时,将会被解释为 arrayLength
,并非单个元素。
// 创建一个只有唯一元素的数组:数字 42。
const arr = [42];// 创建一个没有元素的数组,且数组的长度被设置成 42。
const arr = Array(42);// 上面的代码与下面的代码等价:
const arr = [];
arr.length = 42;
如果 N
不是一个整数,调用 Array(N)
将会报 RangeError
错误,下面的例子说明了这种行为:
const arr = Array(9.3); // RangeError: Invalid array length
如果你需要创建任意类型的单元素数组,安全的方式是使用数组字面量。或者在向数组添加单个元素之前先创建一个空的数组。
你也可以使用 Array.of 静态方法来创建包含单个元素的数组。
const wisenArray = Array.of(9.3); // wisenArray 只包含一个元素:9.3
引用数组元素
因为元素也是属性,你可以使用属性访问器来访问。假设你定义了以下数组:
const myArray = ["Wind", "Rain", "Fire"];
你可以将数组的第一个元素引用为 myArray[0]
,将数组的第二个元素引用为 myArray[1]
,等等...元素的索引从零开始。
备注: 你也可以使用属性访问器来访问数组的其他属性,就像对象一样。
const arr = ["one", "two", "three"];
arr[2]; // three
arr["length"]; // 3
填充数组
你可以通过给数组元素赋值来填充数组,例如:
const emp = [];
emp[0] = "Casey Jones";
emp[1] = "Phil Lesh";
emp[2] = "August West";
备注: 如果你在以上代码中给数组运算符的是一个非整型数值,那么它将作为一个表示数组的对象的属性创建,而不是数组的元素。
const arr = [];
arr[3.4] = "Oranges";
console.log(arr.length); // 0
console.log(Object.hasOwn(arr, 3.4)); // true
你也可以在创建数组的时候去填充它:
const myArray = new Array("Hello", myVar, 3.14159);
// 或
const myArray = ["Mango", "Apple", "Orange"];
理解length:
在实现层面,JavaScript 实际上是将元素作为标准的对象属性来存储,把数组索引作为属性名。
length
属性是特殊的,如果存在最后一个元素,则其值总是大于其索引的正整数。
记住,JavaScript 数组索引是基于 0 的:它们从 0
开始,而不是 1
。这意味着 length
属性将比最大的索引值大 1:
const cats = [];
cats[30] = ["Dusty"];
console.log(cats.length); // 31
你也可以给 length
属性赋值。
写一个小于数组元素数量的值将截断数组,写 0
会彻底清空数组:
const cats = ["Dusty", "Misty", "Twiggy"];
console.log(cats.length); // 3cats.length = 2;
console.log(cats); // [ 'Dusty', 'Misty' ] - Twiggy 已经被移除了cats.length = 0;
console.log(cats); // 输出 [],猫名称的数组现在已经空了cats.length = 3;
console.log(cats); // 输出 [ <3 empty items> ]
遍历数组:
一种常见的操作是遍历数组的值,以某种方式处理每个值。最简单的方法如下:
const colors = ["red", "green", "blue"];
for (let i = 0; i < colors.length; i++) {console.log(colors[i]);
}
forEach() 方法提供了遍历数组元素的其他方法:
const colors = ["red", "green", "blue"];
colors.forEach((color) => console.log(color));
// red
// green
// blue
传递给 forEach
的函数对数组中的每个元素执行一次,数组元素作为参数传递给该函数。未赋值的值不会在 forEach
循环迭代。
注意,在数组定义时省略的元素不会在 forEach
遍历时被列出,但是手动赋值为 undefined
的元素是会被列出的:
const sparseArray = ["first", "second", , "fourth"];sparseArray.forEach((element) => {console.log(element);
});
// first
// second
// fourthif (sparseArray[2] === undefined) {console.log("sparseArray[2] 是 undefined"); // true
}const nonsparseArray = ["first", "second", undefined, "fourth"];nonsparseArray.forEach((element) => {console.log(element);
});
// first
// second
// undefined
// fourth
数组方法:
Array 对象具有下列方法:
concat() 方法连接两个或多个数组并返回一个新的数组。
let myArray = ["1", "2", "3"];
myArray = myArray.concat("a", "b", "c");
// myArray 现在是 ["1", "2", "3", "a", "b", "c"]
join() 方法将数组中的所有元素连接成一个字符串。
const myArray = ["Wind", "Rain", "Fire"];
const list = myArray.join(" - "); // list 现在是 "Wind - Rain - Fire"
push() 方法在数组末尾添加一个或多个元素,并返回数组操作后的 length
。
const myArray = ["1", "2"];
myArray.push("3"); // myArray 现在是 ["1", "2", "3"]
pop() 方法从数组移出最后一个元素,并返回该元素。
const myArray = ["1", "2", "3"];
const last = myArray.pop();
// myArray 现在是 ["1", "2"],last 为 "3"
shift() 方法从数组移出第一个元素,并返回该元素。
const myArray = ["1", "2", "3"];
const first = myArray.shift();
// myArray 现在是 ["2", "3"],first 为 "1"
unshift() 方法在数组开头添加一个或多个元素,并返回数组的新长度。
const myArray = ["1", "2", "3"];
myArray.unshift("4", "5");
// myArray 变成了 ["4", "5", "1", "2", "3"]
slice() 方法从数组提取一个片段,并作为一个新数组返回。
let myArray = ["a", "b", "c", "d", "e"];
myArray = myArray.slice(1, 4); // [ "b", "c", "d"]
// 从索引 1 开始,提取所有的元素,直到索引 3 为止
at() 方法返回数组中指定索引处的元素,如果索引超出范围,则返回 undefined
。它主要用于从数组末尾访问元素的负下标。
const myArray = ["a", "b", "c", "d", "e"];
myArray.at(-2); // "d",myArray 的倒数第二个元素
splice() 方法从数组移除一些元素,并(可选地)替换它们。它返回从数组中删除的元素。
const myArray = ["1", "2", "3", "4", "5"];
myArray.splice(1, 3, "a", "b", "c", "d");
// myArray 现在是 ["1", "a", "b", "c", "d", "5"]
// 本代码从 1 号索引开始(或元素“2”所在的位置),
// 移除 3 个元素,然后将后续元素插入到那个位置上。
reverse() 方法原地颠倒数组元素的顺序:第一个数组元素变为最后一个数组元素,最后一个数组元素变为第一个数组元素。它返回对数组的引用。
const myArray = ["1", "2", "3"];
myArray.reverse();
// 将原数组颠倒,myArray = [ "3", "2", "1" ]
flat() 方法返回一个新数组,所有子数组元素递归地连接到其中,直到指定的深度。
let myArray = [1, 2, [3, 4]];
myArray = myArray.flat();
// myArray 现在是 [1, 2, 3, 4],因为子数组 [3, 4] 已被展平
sort() 方法对数组的元素进行适当的排序,并返回对数组的引用,默认是升序排序。
const myArray = ["Wind", "Rain", "Fire"];
myArray.sort();
// 对数组排序,myArray = ["Fire", "Rain", "Wind"]
indexOf() 方法在数组中搜索 searchElement
并返回第一个匹配的索引。
const a = ["a", "b", "a", "b", "a"];
console.log(a.indexOf("b")); // 1// 再试一次,这次从最后一次匹配之后开始
console.log(a.indexOf("b", 2)); // 3
console.log(a.indexOf("z")); // -1, 因为找不到 'z'
lastIndexOf() 方法的工作原理类似于 indexOf
,但这是从末尾开始,反向搜索。
const a = ["a", "b", "c", "d", "a", "b"];
console.log(a.lastIndexOf("b")); // 5// 再试一次,这次从最后一次匹配之前开始
console.log(a.lastIndexOf("b", 4)); // 1
console.log(a.lastIndexOf("z")); // -1
forEach() 方法对数组中的每个元素执行 callback
并返回 undefined
。
const a = ["a", "b", "c"];
a.forEach((element) => {console.log(element);
});
// 输出:
// a
// b
// c
map() 方法返回由每个数组元素上执行 callback
的返回值所组成的新数组。
const a1 = ["a", "b", "c"];
const a2 = a1.map((item) => item.toUpperCase());
console.log(a2); // ['A', 'B', 'C']
flatMap() 方法先执行 map()
,再执行深度为 1 的 flat()
。
const a1 = ["a", "b", "c"];
const a2 = a1.flatMap((item) => [item.toUpperCase(), item.toLowerCase()]);
console.log(a2); // ['A', 'a', 'B', 'b', 'C', 'c']
filter() 方法返回一个新数组,其中包含 callback
返回 true
的元素。
const a1 = ["a", 10, "b", 20, "c", 30];
const a2 = a1.filter((item) => typeof item === "number");
console.log(a2); // [10, 20, 30]
find() 方法返回 callback
返回 true
的第一个元素。
const a1 = ["a", 10, "b", 20, "c", 30];
const i = a1.find((item) => typeof item === "number");
console.log(i); // 10
findLast() 方法返回 callback
返回 true
的最后一个元素。
const a1 = ["a", 10, "b", 20, "c", 30];
const i = a1.findLast((item) => typeof item === "number");
console.log(i); // 30
findIndex() 方法返回 callback
返回 true
的第一个元素的索引。
const a1 = ["a", 10, "b", 20, "c", 30];
const i = a1.findIndex((item) => typeof item === "number");
console.log(i); // 1
findLastIndex() 方法返回 callback
返回 true
的最后一个元素的索引。
const a1 = ["a", 10, "b", 20, "c", 30];
const i = a1.findLastIndex((item) => typeof item === "number");
console.log(i); // 5
如果 callback
对数组中的每一个元素都返回 true
,则 every() 方法返回 true
。
function isNumber(value) {return typeof value === "number";
}
const a1 = [1, 2, 3];
console.log(a1.every(isNumber)); // true
const a2 = [1, "2", 3];
console.log(a2.every(isNumber)); // false
如果 callback
对数组中至少一个元素返回 true
,则 some() 方法返回 true
。
function isNumber(value) {return typeof value === "number";
}
const a1 = [1, 2, 3];
console.log(a1.some(isNumber)); // true
const a2 = [1, "2", 3];
console.log(a2.some(isNumber)); // true
const a3 = ["1", "2", "3"];
console.log(a3.some(isNumber)); // false
稀疏数组
数组可以包含“空槽”,这与用值 undefined
填充的槽不一样。空槽可以通过以下方式之一创建:
// Array 构造函数:
const a = Array(5); // [ <5 empty items> ]// 数组字面量中的连续逗号:
const b = [1, 2, , , 5]; // [ 1, 2, <2 empty items>, 5 ]// 直接给大于 array.length 的索引设置值以形成空槽:
const c = [1, 2];
c[4] = 5; // [ 1, 2, <2 empty items>, 5 ]// 通过直接设置 .length 拉长一个数组:
const d = [1, 2];
d.length = 5; // [ 1, 2, <3 empty items> ]// 删除一个元素:
const e = [1, 2, 3, 4, 5];
delete e[2]; // [ 1, 2, <1 empty item>, 4, 5 ]
在某些操作中,空槽的行为就像它们被填入了 undefined
那样。
const arr = [1, 2, , , 5]; // 创建一个稀疏数组// 通过索引访问
console.log(arr[2]); // undefined// For...of
for (const i of arr) {console.log(i);
}// 输出:1 2 undefined undefined 5// 展开运算
const another = [...arr]; // "another" 为 [ 1, 2, undefined, undefined, 5 ]
在其他方法,特别是数组迭代方法时,空槽是被跳过的。
const mapped = arr.map((i) => i + 1); // [ 2, 3, <2 empty items>, 6 ]
arr.forEach((i) => console.log(i)); // 1 2 5
const filtered = arr.filter(() => true); // [ 1, 2, 5 ]
const hasFalsy = arr.some((k) => !k); // false// 属性迭代
const keys = Object.keys(arr); // [ '0', '1', '4' ]
for (const key in arr) {console.log(key);
}
// 输出:'0' '1' '4'
// 在对象中使用展开,使用属性枚举,而不是数组的迭代器
const objectSpread = { ...arr }; // { '0': 1, '1': 2, '4': 5 }
多维数组
数组是可以嵌套的,这就意味着一个数组可以作为一个元素被包含在另外一个数组里面。利用 JavaScript 数组的这个特性,可以创建多维数组。
以下代码创建了一个二维数组。
const a = new Array(4);
for (i = 0; i < 4; i++) {a[i] = new Array(4);for (j = 0; j < 4; j++) {a[i][j] = "[" + i + "," + j + "]";}
}
这个例子创建的数组拥有以下行数据:
Row 0: [0,0] [0,1] [0,2] [0,3]
Row 1: [1,0] [1,1] [1,2] [1,3]
Row 2: [2,0] [2,1] [2,2] [2,3]
Row 3: [3,0] [3,1] [3,2] [3,3]
使用数组存储其他属性
数组也可以像对象那样使用,以存储相关信息:
const arr = [1, 2, 3];
arr.property = "value";
console.log(arr.property); // "value"
当一个数组作为字符串和正则表达式的匹配结果时,该数组将会返回相关匹配信息的属性和元素。
附:以上内容均为个人在MDN网站上学习JS的笔记,若有侵权,将在第一时间删除,若有错误,将在第一时间修改。
相关文章:
零基础学习JS--基础篇--索引集合类
数组是由名称和索引引用的值构成的有序列表。 JavaScript 中没有明确的数组数据类型。但是,你可以使用预定义的 Array 对象及其方法来处理应用程序中的数组。Array 对象具有以各种方式操作数组的方法,例如连接、反转和排序。它有一个用于确定数组长度的…...
【硬件工程师面经整理25_AD】
文章目录 1 AD设计电路全流程2 ad和cadence区别-逻辑上的区别 1 AD设计电路全流程 软件AD or 模拟数字? 软件AD:AD设计电路全流程包括以下步骤:选择AD库和添加、画原理图、PCB布局、PCB布线、PCB打样、PCB加工 模拟数字: 需求分…...

神经网络的矢量化,训练与激活函数
我们现在再回到我们的神经元部分,来看我们如何用python进行正向传递。 单层的正向传递: 我们回到我们的线性回归的函数。我们每个神经元通过上述的方法,就可以得到我们的激发值,从而可以继续进行下一层。 我们用这个方法就可以得…...

3.7号freeRtoS
1. 串口通信 配置串口为异步通信 设置波特率,数据位,校验位,停止位,数据的方向 同步通信 在同步通信中,数据的传输是在发送端和接收端之间通过一个共享的时钟信号进行同步的。这意味着发送端和接收端的时钟需要保持…...

瑞芯微 | I2S-音频基础 -1
最近调试音频驱动,顺便整理学习了一下i2s、alsa相关知识,整理成了几篇文章,后续会陆续更新。 喜欢嵌入式、Li怒晓得老铁可以关注一口君账号。 1. 音频常用术语 名称含义ADC(Analog to Digit Conversion)模拟信号转换…...

Linux配置.bashrc文件导致各种命令(vim、sudo)失效。
Linux配置.bashrc文件导致各种命令(vim、sudo)失效。 起因是 nvcc-V一直报错:-bash:nvcc: command not found 踩坑记录:上网一查说是没有配置cuda的环境变量。于是去修改了bashrc文件,在最下面…...

Visual Studio 2022 Version 17.9 新功能
Visual Studio 2022 v17.9 为广大 C 开发者引入了一系列好用的新功能和改进优化。 内存布局 现在,你可以使用【内存布局,Memory Layout】功能以可视化的方式来查看对象,结构体及联合体的内存布局信息,这可比以前需要手动查看内存…...
ArrayList 和 LinkedList 的区别
ArrayList ArrayList 是基于动态数组实现的, 它使用一块连续的内存空间来存储元素,因此访问元素的速度非常快(时间复杂度为 O(1)), 但是,在插入或删除元素时,如果位置不在数组末尾࿰…...
VGG16-CF-VGG11实验报告
说明:VGG16和CF-VGG11是论文《A 3D Fluorescence Classification and Component Prediction Method Based on VGG Convolutional Neural Network and PARAFAC Analysis Method》使用的两种主要模型。其对应代码仓库提供了实验使用的数据集、平行因子分析结果和CNN模型。论文和…...

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的按键扫描、数码管显示按键值、显示按键LED应用
基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的按键扫描、数码管显示按键值、显示按键LED应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍TM1638键盘…...

uniapp使用华为云OBS进行上传
前言:无论是使用华为云还是阿里云,使用其产品的时候必须阅读文档 1、以华为云为例,刚接触此功能肯定是无从下手的情况,那么我们需要思考,我们使用该产品所用到的文档是什么 2、我们要使用obs 文件上传,肯…...

用一个 Python 脚本实现依次运行其他多个带 argparse 命令行参数的 .py 文件
🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 问题描述:在 Windows 环境中,您希望通过一个 Python 脚本来实现特定的自动化任务,该任务需要依次运行其他多个带 argparse 命令行参数的 .py 文件。您希望找到一种简…...
力扣热题100_普通数组_189_轮转数组
文章目录 题目链接解题思路解题代码 题目链接 189. 轮转数组 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] …...

讲解linux下的Qt如何编译oracle的驱动库libqsqloci.so
1.需求 最近linux下的Qt项目中要连接oracle数据库,用户需要我们访问他们的oracle数据库,查询数据 2.遇到的问题 qt连接oracle数据库需要oracle的驱动库libqsqloci.so插件,需要编译下,之前没有编译过,看了网上的…...

SpringCloud Ribbon 负载均衡服务调用
一、前言 接下来是开展一系列的 SpringCloud 的学习之旅,从传统的模块之间调用,一步步的升级为 SpringCloud 模块之间的调用,此篇文章为第三篇,即介绍 Ribbon 负载均衡服务调用 二、概述 2.1 Ribbon 是什么 Spring Cloud Ribbon…...

物联网在智慧城市建设中的关键作用:连接、感知、智能响应
一、引言 随着信息技术的飞速发展,物联网(IoT)技术已经渗透到我们生活的方方面面,特别是在智慧城市建设中发挥着至关重要的作用。智慧城市是指通过运用先进的信息和通信技术,实现城市基础设施、公共服务、交通管理、环…...

安卓7原生相机切到视频崩溃
目录 1、查看日志 2、分析日志、提取重点 3、寻找解决方法 author daisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 daisy.skye_嵌入式,Linux,Qt-CSDN博客daisy.skye擅长嵌入式,Linux,Qt,等方面的知识https://blog.csdn.net/qq_40715266?typeblog 1、查看日志 由于安…...

构建信息蓝图:概念模型与E-R图的技术解析
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua,在这里我会分享我的知识和经验。&#x…...

docker拉取镜像失败的解决方案大全
更换国内源 创建或修改 /etc/docker/daemon.json 文件,修改: {"registry-mirrors" : ["https://registry.docker-cn.com","http://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn","https:…...

Axure Cloud如何给每个原型配置私有域名
需求 在原型发布之后,自动给原型生成一个独立访问的域名,类似http://u591bi.axshare.bushrose.cn,应该如何配置呢? 准备事项 已备案域名 如何备案?阿里云备案流程 已安装部署Axure Cloud 如何安装部署,请…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...