admin管理员组文章数量:1565292
JavaScript 数组
数组的概念
1.之前学习的变量,只能存储一个值。如果我们想存储班级中所有学生的姓名,那么该如何存储呢?
答:可以使用数组(Array)。数组可以把一组相关的数据一起存放,并提供方便的访问(获取)方式。
2.什么是数组呢?
答:数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。数组是种将一组数据存储在单个变量名下的优雅方式。
数组的创建方式
Js中创建数组有两种方式:
- 利用 new 创建数组
- 利用数组字面量创建数组(常用)
利用 new 创建数组
var arr = new Array();
- 这种方式暂且了解,等学完对象再看
- 注意 Array(),A要大写
利用数组字面量创建数组(常用)
var arr = [];
- 我们数组里面的数据一定用逗号分隔
- 数组里面的数据 比如1,2, 我们称为数组元素
- 数组的字面量是方括号[]
- 声明数组并赋值称为数组的初始化
数组元素的类型
数组中可以存放任意类型的数据,例如字符串,数字,布尔值等
获取数组中的元素
数组的索引
索引(下标):用来访问数组元素的序号(数组下标从0开始)。
- 数组可以通过索引来访问、设置、修改对应的数组元素,我们可以通过“数组名[索引]”
的形式来获取数组中的元素。 - 这里的访问就是获取得到的意思
var arr1 =[1, 2, 'zhangsan', true];
console.log(arr[2]); // 结果是zhangsan
遍历数组
遍历:就是把数组中的每个元素从头到尾都访问一次(类似我们每天早上学生的点名)。
- 因为我们的数组索引号从0开始 ,所以 i 必须从 开始 i< 3
- 输出的时候 arr[i] i 计数器当索引号来用
数组的长度
使用“数组名.length”可以访问数组元素的数量(数组长度)。
- 数组的长度是元素个数 不要跟索引号混淆
- arr.length 动态监测数组元素的个数 当我们的数组长度发生变化,加一个数组或者减去一个数组 不会产生影响
提问
1.什么是遍历?
把数组中的每个元素从头到尾都访问一次
2.我们通过什么来遍历数组里面的元素?
for循环
3.for里面的i是什么?当什么使用? for里面的数组元素怎么写?
i是计数器,当索引号使用,arr[i] 是数组元素 第i个数组元素
4.怎么获取数组的长度?
“数组名.length”
5.数组索引号和数组长度有什么关系?
索引号从0开始,数组长度是元素个数
案例:数组求和及平均值
var arr = [2, 6, 1, 7, 4];
var sum = 0;
var average = 0;
// 为什么i<arr.length 没有等于号 因为.length代表元素个数 数组中五个元素 只需加四次
for (var i = 0, i < arr.length; i++) {
// 为什么var i = 0,因为数组中arr[i] 第一个数组元素的索引号就是0
sum += arr[i];
}
average = sum / arr.length;
console.log(sum, average);
案例:数组最大值
var arr = [2, 6, 1, 77, 52, 25, 7, 99];
var max = arr[0]; // 这个数组的目的是将比较过的 大于的 数组元素存到里面
// 为什么i<arr.length 没有等于号 因为.length代表元素个数 数组中8个元素 只需相互比较7次 所以不需要等于号
for (var i = 1; i < arr.length; i++){
// 为什么var i = 1,只要不是数组中的数字 并且比数组中的任意一个数字小都可以 比如是负数 null空值 也可以var i = 0,从0开始的话就是数组中的第一个数字和第一个数字做比较
if (arr[i] > max) {
max = arr[i];
}
}
console.log('该数组里面的最大值是:' + max);
案例:数组转换为分割字符串
var arr = [ 'red', 'green', 'blue', 'pink'];
var str = ''; // 这里可以是‘’ 也可以是null 空置 不可以是数字 文字 或者 undefined NaN
for (var i = 0; i < arr.length; i++) {
str += arr[i] + '|';
}
console.log(str);
数组中新增元素
可以通过修改length长度以及索引号增加数组元素
通过修改length长度新增数组元素
- 可以通过修改length长度来实现数组扩容的目的
- length属性是可读写的
var arr = ['red', 'green', 'blue'];
console.log(arr.length);
arr.length = 5; // 当我们把数组的长度原来是3个,改成5个,里面现在因该有五个
console.log(arr);
console.log(arr[3]); // 结果是undefined
console.log(arr[4]); // 结果是undefined
其中索引号是4,5,6的空间没有给值,就是声明变量未给值,默认值就是undefined.
通过修改数组索引新增数组元素
- 可以通过修改数组索引的方式追加数组元素
- 不能直接给数组名赋值,否则会覆盖掉以前的数据
案例 数组新增元素:新建一个数组,里面存放10个整数(1~10)
var arr = [];
for (var i = 0; i < 10; i++) {
// arr = i; 不要直接给数组名赋值,否则以前元素都没了
arr[i] = i + 1;
}
console.log(arr);
案例 筛选数组 要求将数组[2, 0, 6, 1, 77, 0, 52, 0, 25, 7]中大于等于10的元素选出来,放入新数组。
方法一:
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
var j = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] >=10) {
// 新数组索引号应该从0开始
newArr[j] = arr[i];
j++;
}
}
console.log(newArr);
方法二:
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
// 刚开始 newArr.length 就是0
// newArr.length 自动检测 第一个存进去的是77,索引号是0,如果第二个52,length自动检测,52的索引号变成2
for (var i = 0; i < arr.length; i++) {
if (arr[i] >=10) {
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
数组案例
案例一:删除指定数组元素
要求:将数组[2, 0, 6, 1, 77, 0, 52, 0, 25, 7]中的0去掉后,形成一个不包含0的新数组
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] != 0) {
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
案例二:翻转数组
要求将数组['red', 'green', 'blue', 'pink', 'purple']的内容翻过来存放
var arr = ['red', 'green', 'blue', 'pink', 'purple'];
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
console.log(newArr);
案例三:数组排序(冒泡排序)
冒泡排序:是一种算法,把一系列的数据按照一定的顺序进行排列显示(从小到大或从大到小)。
例如,我们可以将数组[5,4,3,2, 1]中的元素按照从小到大的顺序排序,输出:1,2,3,4,5
冒泡排序是一种简单的排序算法,它重复地走访过要排序的数列,一次比较两元素,如果他们的顺序措误就把他们交换过来,走访数列的工作是重复地进行直到没有再需要换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮"到数列的顶端。
分析:
var arr = [5, 4, 3, 2, 1,];
// 外层循环几趟 趟数
for (var i = 0; i <= arr.length - 1; i++) {
// 里面的循环 每一趟的交换次数
for (var j = 0; j < arr.length - i - 1; j++) {
// 内部交换2个变量的值 前一个和后一个数组元素相比较
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + i];
arr[j + 1] = temp;
}
}
}
console.log(arr);
JavaScript 函数
函数的概念
在JS里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量重复使用虽然 for循环语句也能实现一些简单的重复操作,但是比较具有局限性,此时我们就可以使用JS 中的函数.
函数:就是封装了一段可被重复调用执行的代码块。通过此代码块可以实现大量代码的重复使用。
函数的使用
函数在使用时分为两步:
- 声明函数
- 调用函数
1.声明函数
function 函数名() {
// 函数体
}
function 函数的意思 声明函数的关键字 全部小写
函数是做某件事情,函数名一般是动词 sayHi
函数不调用,自己不执行
2.调用函数
函数名();
调用函数的时候千万不要忘记加小括号()
3.函数的封装
- 函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
- 简单理解:封装类似于将电脑配件整合组装到机箱中(类似快递打包)
案例:利用函数计算1~100之间的累加和
function getSum() {
var sum = 0;
for (var i = 1; i <= 100; i++) {
sum += i;
}
conlose.log(sum);
}
getSum();
提问:
1.函数是做什么的(作用)?
大量代码的重复使用
2.声明函数用什么关键词?
function
3.如何调用函数?
函数名();
4.封装是什么意思?
把一个或者多个功能通过函数的方式封装起来
函数的参数
形参和实参
在声明函数时,可以在函数名称后面的小括号中添加一些参数,这些参数被称为形参 ,而在调用该函数时,同样也需要传递相应的参数,这些参数被称为实参。
参数的作用:在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去。
案例1:利用函数求任意两个数的和
function getSum(num1,num2) {
console.log(num1 + num2);
}
getSum(1, 3);
getSum(3, 8);
案例2:利用函数求任意两个数之间的和
function getSums(start, end) {
var sum = 0;
for (var i = start; i <= end; i++) {
sum += i;
}
console.log(sum);
}
getSums(1, 100);
注意点:
- 多个参数之间用逗号隔开
- 形参可以看作是不用声明的变量
函数形参和实参个数不匹配问题
注意:
- 在JavaScript中,形参的默认值是undefined
- 我们尽量让实参的个数和形参相匹配
小结
- 函数可以带参数也可以不带参数
- 声明函数的时候,函数名括号里面的是形参,形参的默认值为undefined
- 调用函数的时候,函数名括号里面的是实参
- 多个参数中间用逗号分隔
- 形参的个数可以和实参个数不匹配,但是结果不可预计,我们尽量要匹配
函数的返回值
return 语句
有的时候,我们会希望函数将值返回给调用者,此时通过使用 return 语句就可以实现。
函数的返回值格式:
function 函数名() {
return 需要返回的结果;
}
函数名();
(1)我们函数只是实现某种功能,最终的结果需要返回给函数的调用者 函数名() 通过return 实现
(2)只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名() = return 后面的结果
例如:
function cook(aru) {
return arn;
}
console.log(cook('大肘子'));
示例1:求任意两个数的和
function getSum(num1, num2) {
return num1 + num2;
}
console.log(getSum(1, 2));
案例2:利用函数求任意两个数的最大值
方法1是if else语句
方法2是三元表达式
function getMax(num1, num2) {
if (num1 > num2) {
return num1;
} else {
return num2;
}
}
console.log(getMax(1, 3));
----------------------------------------------------------
function getMax(num1, num2) {
return num1 > num2 ? num1 : num2;
}
console.log(getMax(11, 12));
案例3:利用函数求任意一个数组中的最大值
求数组[5,299,101,6777中的最大数值
function getArrMax(arr) {
var max = arr[0];
for (var i = 1; i <= arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
var re = getArrMax([5,2,99,101,67,77]);
console.log(re);
return 终止函数
return语句之后的代码不被执行
return 的返回值
return 只能返回一个值。如果用逗号隔开多个值,以最后一个为准
函数没有 return 返回 undefined
函数都是有返回值的
1.如果有return则返回return 后面的值
2.如果没有return 则返回undefined
break ,continue ,return 的区别
- break :结束当前的循环体(如for、while)
- continue:跳出本次循环,继续执行下次循环(如for、while )
- return:不仅可以退出循环,还能修返回return 语句中的值,同时还可以结束当前的函数体内的代码
arguments的使用
当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。
arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:
-
具有length属性
-
按索引方式储存数据
-
不具有数组的push(),pop () 等方法
function fn() {
console.log(arguments);
console.log(arguments.length);
}
fn(1,2,3);
案例1:利用函数求任意个数的最大值
function getMax() {
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
console.log(getMax(1,2,3));
console.log(getMax(1,2,3,4,5));
console.log(getMax(11,2,34,444,5,100));
案例2:利用函数封装方式,翻转任意一个数组
function reverse(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
return newArr;
}
var arr1 = reverse([1, 3, 4, 6, 9]);
console.log(arr1);
var arr2 = reverse(['red', 'pink', 'blue']);
console.log(arr2);
案例3:利用函数封装方式,对数组排序--冒泡排序
function sort(arr) {
for (var i=0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
var arr1 = sort([1, 4, 2, 9]);
console.log(arr1);
var arr2 = sort([11, 7, 22, 999]);
console.log(arr2);
案例4:判断闰年
要求:输入一个年份,判断是否是年(年:能被4整除并且不能被100整数,或者能被400整除)
function isRunYear(year) {
var flag = false;
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
console.log(isRunYear(2000));
console.log(isRunYear(1999));
函数可以调用另外一个函数
因为每个函数都是独立的代码块,用于完成特殊任务,因此经常会用到函数相互调用的情况
function fn1() {
console.log(11);
fn2();
}
fn1();
function fn2() {
console.log(22);
}
案例1:
输出结果为:
案例2:用户输入年份,输出当前年份2月份的天数
如果是闰年,则2月份是29天,如果是平年,则2月份是28天
function backDay() {
var year = prompt('请输入年份:');
if (isRunYear(year)) {
alert('当前年份是闰年,2月份有29天');
} else {
alert('当前年份是平年,2月份有28天');
}
}
backDay();
函数的两种声明方式
1.利用函数关键字自定义函数(命名函数)
function 函数名() {
// 函数体
}
函数名();
2.函数表达式
var 变量名 = function(){};
比如:
var fun = function() {
console.log('我是函数表达式');
}
fun();
- fun是变量名 不是函数名
- 函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值 而 函数表达式里面存的是函数
- 函数表达式也可以进行传递参数
例如:
var fun = function(aru) {
console.log(aru);
}
fun('张三'); // 输出结果是张三
JavaScript作用域
作用域
概述
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高少程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
简单理解:就是代码名字(变量)在某个范围内起作用和效果。 目的是 为了提高程序的可靠性,减少命名冲突。
Js的作用域(es6)之前
全局作用域
整个script标签 或者是一个单独的js文件
局部作用域
在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用
比如在function fn()函数里面的就成为局部作用域
变量的作用域
分类
在JavaScript中,根据作用域的不同,变量可以分为两种:
- 全局变量
- 局部变量
全局变量
在全局作用域下声明的变量 或者 (在函数外部定义的变量)
- 全局变量在代码的任何位置都可以使用
- 在全局作用域下var声明的变量是全局变量
- 特殊情况下,在函数内不使用 var声明的变量也是全局变量(不建议使用)
注意: 如果在函数内部 没有声明直接赋值的变量也属于全局变量
局部变量
在局部作用域下声明的变量 或者(在函数内部定义的变量)
- 局部变量只能在该函数内部使用
- 在函数内部var声明的变量是局部变量
- 函数的形参实际上就是局部变量
注意:函数的形参也可以看作是局部变量 外面的不可以使用它
全局变量和局部变量的区别
从执行效率来看全局变量和局部变量
(1)全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
(2)局部变量 当我们程序执行完毕就会销毁,比较节约内存资源
Js 没有块级作用域(现阶段我们js 没有 块级作用域 ES6之前)
块级作用域就是{}里面包含的
比如说: if for
作用域链
- 只要是代码,就至少有一个作用域
- 写在函数内部的局部作用域
- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
- 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链
案例1
案例2
JavaScript 预解析
预解析
JavaScript代码是由浏览器中的JavaScript解析器来执行的。JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行。
步骤执行顺序
1.预解析
js引擎会把 js 里面所有的 var 还有 function 提升到当前作用域的最前面
2.代码执行
按照代码书写的顺序从上往下执行
变量预解析和函数预解析
预解析分为 变量预解析 (变量提升) 和 函数预解析 (函数提升)
(1) 变量提升 就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作
console.log(num);
var num = 10;
--------------------------------------
var num;
console.log(num);
num = 10;
fun();
var fun= function() {
console.log(22);
}
------------------------------------
var fun;
fun();
fun = function() {
console.log(22);
}
(2)函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数
简单理解:函数表达式 调用必须写在函数表达式的下面
预解析案例
注意:
JavaScript 对象
对象
什么是对象?
现实生活中:万物皆对象,对象是一个具体的事物,看得见摸得着的实物。例如,一本书、一辆汽车、一个人可以是“对象”一个数据库、一张网页、一个与远程服务器的连接也可以是“对象”。
在JavaSript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
对象是由属性和方法组成的。
- 属性:事物的特征,在对象中用属性来表示(常用名词)
- 方法:事物的行为,在对象中用方法来表示(常用动词)
为什么需要对象
保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组。如果要保存一个人的完整信息呢?
创建对象的三种方式
在JavaScript中,现阶段我们可以采用三种方式创建对象(object):
- 利用 字面量 创建对象
- 利用 new Object 创建对象
- 利用 构造函数 创建对象
利用 字面量 创建对象
对象字面量:就是花括号 {} 里面包含了表达这个具体事物(对象)的属性和方法
1.利用对象字面量创建对象{}
// var obj = {}; // 创建了一个空的对象
var obj = {
uname: '张三丰',
age : 18,
sex: '男',
sayHi: function() {
console.log('你好~');
}
}
创建对象重点:
(1)里面的属性或者方法 我们采用键值对的形式 键(属性名): 值(属性值)
(2)多个属性或者方法中间用逗号隔开
(3)方法冒号后面跟的是一个匿名函数
2.使用对象
(1)调用对象的属性我们采取 对象名.属性名 中间的点(.)我们理解为 的
比如: console.log(obj.uname);
(2)第二种方法 对象名['属性名']
比如: console.log(obj['age']);
(3)调用对象的方法 sayHi 对象名.方法名 千万别忘记添加小括号
比如: obj.sayHi();
变量、属性、函数、方法总结
1.变量和属性相同点 都是用来存储数据的
比如:
var num = 10;
var obj = {
age = 18
}
console.log(obj.age); // 结果是18
console.log(age); // 属性不能直接输出 必须是对象.属性
变量:单独声明并赋值 使用的时候直接写变量名 单独存在
属性:在对象里面的不需要声明的 使用的时候必须是 对象.属性
2.函数和方法的相同点 都是实现某种功能 做某种事
函数:是单独声明 并且调用的 函数名() 单独存在的
方法: 在对象里面 调用的时候 对象.方法()
利用 new Object 创建对象
跟我们前面学的 new Array()原理一致
创建:
var obj = new Object(); // 创建了一个空的对象
obj.uname = '张三'; // 在obj对象里面 创建了uname: '张三'
obj.age = 18; // 在obj对象里面 创建了age: 18
obj.sex = '男'; // 在obj对象里面 创建了sex: '男'
obj.sayHi=function() {
console.log('你好~');
}
重点:
(1)我们是利用 等号 = 赋值的方法 添加对象的属性和方法
(2)每个属性和方法之间用 分号结束
(3)new Object 中O要大写
调用对象(跟上面一样的三种方法):
(1)调用对象的属性我们采取 对象名.属性名 中间的点(.)我们理解为 的
比如: console.log(obj.uname);
(2)第二种方法 对象名['属性名']
比如: console.log(obj['age']);
(3)调用对象的方法 sayHi 对象名.方法名 千万别忘记添加小括号
比如: obj.sayHi();
利用 构造函数 创建对象
为什么需要使用构造函数创建对象?
因为我们前面两种(利用 new Object 创建对象、利用 构造函数 创建对象)的方式一次只能创建一个对象
我们一次创建一个对象,里面很多的属性和方法是大量相同的 我们只能复制
因此我们可以利用函数的方法 重复这些相同的代码,我们就把这个函数称为 构造函数
为什么叫构造函数而不叫函数?
因为里面封装的不是普通的代码,而是 对象
构造函数定义:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面
简单来说 构造函数 :就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面
构造函数的语法格式
先声明函数
function 构造函数名() {
this.属性 = 值; // this 当前的意思
this.方法 = function(){}
}
new 构造函数名();
举例:创建四大天王的对象 相同的属性:名字 年龄 性别 相同的方法:唱歌
----
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang) {
console.log(sang);
}
}
var ldh = new Star('刘德华', 18, '男');
console.log(typeof ldh); // 测试调用是否返回对象 结果是object 调用函数返回的是对象
console.log(ldh.name); // 输出刘德华的名字
console.log(ldh['sex']); // 输出刘德华的性别
ldh.sing('冰雨');
var zxy = new Star('张学友', 19, '男');
console.log(zxy.name);
console.log(zxy.age);
zxy.sing('李香兰');
重点:
(1)构造函数名字首字母要大写
(2)我们构造函数不需要return 就可以返回结果
(3)我们调用构造函数 必须使用new
(4)我们只要new Star() 调用函数就创建一个对象
(5)我们的属性和方法前面必须添加 this
构造函数与对象的联系
1.构造函数 如Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class) 比如说明星
2.对象 如newStars(),特指某一个,通过new关键字创建对象的过程我们也称为对象实例化,是一个具体的事物 比如刘德华
3.我们利用创造函数创建对象的过程我们也称为对象的实例化
new关键字
new关键字执行过程
1.new 构造函数可以在内存中创建了一个空的对象
2.this 就会指向刚才创建的空对象
3.执行构造函数里面的代码 给这个空对象添加属性和方法
4.返回这个对象(所以构造函数里面不需要return)
遍历对象属性
for...in语句 用于对数组或者对象的属性进行循环操作。
语法格式:
for(变量 in 对象) {
// 输出语句
}
比如:
var obj = {
name: '张三',
age: 18,
sex: '男'
}
for (var k in obj) {
console.log(k); // k 变量输出得到的是属性名 不一定非要是k 可以是任意
console.log(obj[k]); // obj[k] 输出得到的是属性值
我们使用 for in 里面的变量 我们喜欢写 k 或者 key
对象小结
- 对象可以让代码结构更清晰
- 对象复杂数据类型object。
- 本质:对象就是一组无序的相关属性和方法的集合。
- 构造函数泛指某一大类,比如苹果,不管是红色苹果还是绿色苹果,都统称为苹果
- 对象实例特指一个事物,比如这个苹果、正在给你们讲课的老师等
- for...in 语句用于对对象的属性进行循环操作
作业
1.创建一个电脑对象,该对象要有颜色、重量、品牌、型号,可以看电影、听音乐、打游戏和敲代码.
2.创建一个按钮对象,该对象中需要包含宽,高,背景颜色和点击行为。
3.创建一个车的对象,该对象要有重量、颜色、牌子,可以载人、拉货和耕田
4.写一个函数,实现反转任意数组
5.写一个函数,实现对数字数组的排序
JavaScript 内置对象
内置对象
JavaScript中的对象分为3种:
- 自定义对象
- 内置对象
- 浏览器对象
前面两种对象是JS基础内容,属于ECMASript;第三个浏览器对象属于我们JS独有的,我们JS API讲解
内置对象:就是指JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)。
内置对象最大的优点:就是帮助我们快速开发
JavaScript提供了多个内置对象:Math、Date 、Array、string等
查文档
MDN
学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过MDN W3C来查询。(推荐MDN)
Mozilla开发者网络(MDN)提供了有关开放网络技术(Open Web )的信息,包括HTML、CSS和万维网及HTML5应用的API。
MDN网址:MDN Web DocsThe MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps.https://developer.mozilla/zh-CN/
怎么学习对象中的方法
1.查阅该方法的功能
2.查看里面参数的意义和类型
3.查看返回值的意义和类型
4.通过demo进行测试
Math对象(数学对象)
概述
Math数学对象 不是一个构造函数 ,所以我们不需要new 来调用 而是直接使用里面的属性和方法即可。
Math 对象不是构造函数,它具有数学常数和函数的属性和方法。跟数学相关的运算(求绝对值,取整、最大值等)可以使用Math中的成员。
比如:
console.log(Math.PI);
// Math.PI 是圆周率 直接调用 直接使用 结果是3.141592653589793
--------
Math.max()
函数返回作为输入参数的最大数字console.log(Math.max(1, 3, 2)); // 结果输出最大数字是 3
案例:封装自己的数学对象
利用对象封装自己的数学对象 里面有 PI(圆周率) 最大值 和 最小值
var myMath = {
// PI(圆周率)
PI: 3.141592653589793,
// 最大值
max: function() {
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
// 最小值
min: function() {
var min = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] < min) {
min = arguments[i];
}
}
return min;
}
}
console.log(myMath.PI); // 调用
console.log(myMath.max(1, 5, 9));
console.log(myMath.min(1, 5, 9));
注意
floor 翻译为 地板
ceil 翻译为 天花板
Math.PI // 圆周率
Math.floor() // 向下取整
Math.ceil() // 向上取整
Math.round() // 四舍五入版 就近取整注意 -3.5结果是-3
Math.abs () // 绝对值
Math.max() / Math.min() // 求最大和最小值
random() 返回随机数方法
1.Math.random()
函数返回一个浮点数,随机数在范围从0 到小于1(0 =< x < 1),也就是说,从 0(包括 0)往上,但是不包括 1(排除 1),然后您可以缩放到所需的范围。实现将初始种子选择到随机数生成算法;它不能被用户选择或重置。
2.这个方法里面不跟参数
3.代码验证
输出结果为
每次的结果都随机 不一样 有几率会抽到0
4.我们想要得到两个数之间的随机整数 并且 包含这2个整数
公式为:
Math.random() * (max - min) + min;
比如:输出两个数之间的随机整数
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
console.log(getRandom(1, 10)); // 结果可能是8 也可能是6 比1大比10小
5.随机点名
var arr = ['张三', '李四', '王二', '麻子'];
console.log(arr[0]); // 不能这样写 这样写的话就会每次抽中索引号为0 就是第一个 张三
正确的是:
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
console.log(arr[getRandom(0, 4)]); // 随机取0 和 4之间的
console.log(arr[getRandom(0, arr.length-1)]);
案例:
思路:
1.随机生成一个1~1 的整数 我们需要用到 Math.random() 方法。
2.需要一直猜到正确为止,所以需要一直循环。
3.while 循环更简单
4.核心算法:使用 if else if 多分支语句来判断大于、小于、等于。
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
var random = getRandom(1, 10);
while(true) { // 死循环
var num = prompt('你来猜?输入1~10之间的数字');
if (num > random) {
alert('你猜大了');
}else if(num < random) {
alert('你猜小了');
}else {
alert('恭喜你,猜对了');
break; // 退出整个循环 结束程序
}
}
Date 日期对象
概述
- 是一个构造函数 必须使用new 来调用创建我们的日期对象
var arr = new Array(); // 创建了一个数组对象
var obj = new Object(); // 创建了一个对象实例
使用方法
1.使用Date 如果没有参数 返回当前系统的当前时间
var date = new Date();
console.log(date);
// 输出结果是 Thu Jul 27 2023 22:16:25 GMT+0800 (中国标准时间)
2.参数常用写法 数字型 2019,10,01 或者是 字符串型 ‘2019-10-1 18:08:8’
var date = new Date(2019, 10, 1);
console.log(date);
// 返回的是11月 不是10月 这个地方错了
---------
var date = new Date('2019-10-1 18:08:8');
console.log(date);
// 返回的是10月 字符串型的对了
日期格式化
我们想要2019-8-8 8:8:8格式的日期,要怎么办?
需要获取日期指定的部分,所以我们要手动的得到这种格式。
var date = new Date();
console.log(date.getFullYear()); // 返回当前日期的年份
console.log(date.getMonth() + 1); // 记得月份加 1
// 返回当前日期的月份 返回的月份小一个月 我们是1~12月 国外是0~11月
console.log(date.getDate()); // 返回当前是几号
console.log(date.getDay()); // 返回当前是周几 周一是周一 周六是周六 周日是0
我们写一个 2019年 5月 1日 星期三
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
var day = date.getDay();
var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
console.log('今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day]);
格式化 时分秒:
获取日期的总的毫秒形式
Date对象是基于1970年1月1日(世界标准时间)起的毫秒数
为什么计算机起始时间从1970年开始?
我们经常利用总的毫秒数来计算时间,因为它更精确
获得Date总的毫秒数 不是当前时间的毫秒数 而是距离1970年1月1号过了多少毫秒数
方法一:通过 valueOf() getTime()
var date = new Date();
console.log(date.valueOf()); // 就是我们 现在的时间距离1970年1月1日的总毫秒数
console.log(date.getTime()); // 就是我们 现在的时间距离1970年1月1日的总毫秒数
方法二:简单写法 (最常用写法)
var date = +new Date(); // +new Date() 前面写个+号 返回的就是总的毫秒数
console.log(date);
方法三: H5新增的 (低版本浏览器不识别)
console.log(Date.now());
案例:倒计时效果
分析:
- 核心算法:输入的时间减去现在的时间就是剩余的时间,即倒计时,但是不能拿着时分秒相减,比如05分减去25分,结果会是负数的
- 用时间戳来做。用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数。
- 把剩余时间总的毫秒数转换为天、时、分、秒(时间戳转换为时分秒)
转换公式如下:
- d =parseInt(总秒数/60/60/24); //计算天数
- h = parseInt(总秒数/60/60%24) //计算小时
- m = parseInt(总秒数/60%60); // 计算分数
- s =parseInt(总秒数%60); //计算当前秒数
function countDown(time) {
var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
var inputTime= +new Date(time); // 返回的是用户输入时间总的毫秒数
// var times = inputTime - nowTime; // time是剩余时间总的毫秒数
var times = (inputTime - nowTime) / 1000; // 剩余时间总的秒数
var d = parseInt(times / 60 / 60 / 24); //计算天数
d = d < 10 ? '0' + d : d ;
var h = parseInt(times / 60 / 60 % 24); //计算小时
h = h < 10 ? '0' + h : h ;
var m = parseInt(times / 60 % 60); // 计算分数
m = m < 10 ? '0' + m : m ;
var s = parseInt(times % 60); //计算当前秒数
s = s < 10 ? '0' + s : s ;
return d + '天' + h + '时' + m + '分' + s + '秒';
}
console.log(countDown('2030-5-1 18:00:00'));
var date = new Date();
console.log(date);
数组对象
创建方法
1.利用数组字面量
var arr = [1, 2, 3];
console.log(arr[0]); // 输出数组中的第0个元素
2. 利用new Arry()
var arr1 = new Array(); // 创建了一个空的数组
// var arr1 = new Array(2); // 如果小括号里面就一个数字,那么是创建了一个包含两个空元素的数组(数组长度)
var arr1 = new Array(2, 3) // 等价于 [2,3] 这样写表示里面有2个数组元素 是 2和3
console.log(arr1);
检测是否为数组
(1)instanceof 运算符 它可以用来检测是否为数组
var arr = [];
// arr instanceof Array 意为 输出arr 结果是数组吗,是的话结果是true
console.log(arr instanceof Array); // 结果为 true
var obj = {}; // 大括号是对象
console.log(obj instanceof Array); // 结果为false
示例:翻转数组
function reverse(arr) {
// arr instanceof Array 如果值是一个数组 则执行里面的
if (arr instanceof Array) {
var newArr = [];
for (var i =arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
return newArr;
} else { // 如果不是则执行返回这句话
return '这个参数要求必须是数组格式 如[1,2,3]';
}
}
console.log(reverse([2,3,4]));
console.log(reverse(7,8,9));
(2)使用js封装好的检测数组代码 Array.isArray(参数);
注意:H5新增的方法 ie9以上版本支持
var arr = [];
console.log(Array.isArray(arr)); // 结果为 true
添加删除数组元素的方法⭐⭐
方法名 | 说明 | 返回值 |
---|---|---|
push(参数值1...) | 末尾添加一个或多个元素,注意修改原数组 | 并返回新的长度 |
pop() | 删除数组最后一个元素,把数组长度减1 无参数、修改元素组 | 返回它删除的元素的值 |
unshift(参数1...) | 向数组的开头添加一个或更多元素,注意修改原数组 | 并返回新的长度 |
shift() | 删除数组的第一个元素,数组长度减1 参数、修改原数组 | 并返回第一个元素的值 |
添加数组元素
1. push() push意为推 在我们数组的末尾 添加一个或者多个数组元素
var arr = [1,2,3];
arr.push(4,'张三'); // 意为 把4和张三 添加给我们的arr数组 所以现在有5个元素
注意:
- push 是可以给数组追加新的元素
- push() 参数直接写 数组元素就可以了
- push完毕之后,返回的结果是 新数组的长度
- 原数组也会发生变化(比如说 push完之后上面的arr原数组个数也会跟着变成5)
2. unshift() 在我们数组的开头 添加一个或者多个数组元素
var arr = [1,2,3];
// arr.unshift('张三',0); // 输出结果为 ['张三',0,1,2,3]
console.log(arr.unshift(4,'张三')); // 输出数组元素 输出结果为 5 分别是['张三',0,1,2,3]
console.log(arr); // 输出数组
注意:
- unshift 是可以给数组追加新的元素
- unshift() 参数直接写 数组元素就可以了
- unshift完毕之后,返回的结果是 新数组的长度
- 原数组也会发生变化
删除数组元素
1. pop() 删除数组的最后一个元素 注意:一次只能删除一个
var arr = [1,2,3,4,5,6,7];
console.log(arr.pop()); // 返回值为7 不是总数为7 而是输出的是删除的那个元素
console.log(arr);
注意:
- pop 是可以给删除数组的最后一个元素 一次只能删除一个
- pop() 没有参数
- pop完毕之后 返回的结果是 删除的那个元素
- 原数组也会发生变化
2. shift() 删除数组的开头第一个元素 注意:一次只能删除一个
var arr = [1,2,3,4,5,6,7];
console.log(arr.shift()); // 返回值为1 返回值是删除的那个元素
console.log(arr);
注意:
- shift 是可以给删除数组的开头第一个元素 一次只能删除一个
- shift() 没有参数
- shift完毕之后 返回的结果是 删除的那个元素
- 原数组也会发生变化
案例:筛选数组
有一个包含工资的数组[1500,1200,2000,2100,1800],要求把数组中工资超过2000的删除,剩余的放到新数组里面
var arr = [1500,1200, 2000, 2100,1800];
var newArr = [];
for (var i = 0; i <= arr.length; i++) {
if (arr[i] < 2000) {
// 以前的方法 将筛选出大于2000的元素 存入 newArr里面的第newArr.length个数组 因为
// newArr.length最先是从0开始排号的
// newArr[newArr.length] = arr[i];
// 新方法 意为 把筛选出来的新数组元素 添加给新数组
newArr.push(arr[i]);
}
}
console.log(newArr);
数组排序
方法名 | 说明 | 是否修改原数组 |
---|---|---|
reverse() | 颠倒数组中元素的顺序,无参数 | 该方法会改变原来的数组 返回新数组 |
sort() | 对数组中的元素进行排序 | 该方法会改变原来的数组 返回新数组 |
1.翻转数组
var arr = ['张三', '李四' ,'王二']
arr.reverse();
console.log(arr); //["王二", "李四", "张三"]
2.数组排序(冒泡排序)
var arr1 = [3,4,7,1];
arr1.sort();
console.log(arr1); // 结果是[1,3,4,7] 单位数字是可以的
--------
var arr2 = [13,4,7,1,77];
arr1.sort();
console.log(arr2); // 结果是[1,13,4,7,77] 多位数字是不可以
3. sort冒泡排序完美写法
var arr1 = [13,4,7,1,77];
arr1.sort(function(a, b) {
return a - b ; //按照升序的排列 降序是b - a
});
console.log(arr1); // 结果是[1,4,7,13,77] 多位数字可以实现效果
数组索引方法
方法名 | 说明 | 返回值 |
---|---|---|
indexOf() | 数组中查找给定元素的第一个索引 | 如果存在返回索引号 如果不存在,则返回-1 |
lastlndexOf() | 在数组中的最后一个索引 | 如果存在返回索引号 如果不存在,则返回-1 |
返回数组元素索引号的方法 indexOf(数组元素)
1.作用就是返回该数组元素的索引号
var arr = ['张三', '李四','王二', '麻子'];
console.log(arr.indexOf('王二')); // 返回值是 2
2.如果有多个相同的值,它只返回第一个满足条件的索引号
var arr = ['张三', '李四','王二', '麻子', '麻子'];
console.log(arr.indexOf('麻子')); // 返回值是 3 它只返回第一个满足条件的索引号
3.如果在该数组里找不到该元素返回 -1
var arr = ['张三', '李四','王二'];
console.log(arr.indexOf('麻子')); // 返回值是 -1 找不到该元素
indexOf() 和 lastlndexOf() 的区别
- indexOf() 是从前往后查找
- lastlndexOf() 是从后往前查找
- 如果有多个相同的值,indexOf() 和 lastlndexOf() 返回值不一样
案例:数组去重(重点案例)
有一个数组['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']要求去除数组中重复的元素
案例分析:
- 目标:把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个,放到新数组中去重
- 核心算法:我们遍历旧数组,然后拿着旧数组元素去查询新数组,如果该元素在新数组里面没有出现过,我们就添加否则不添加。
- 我们怎么知道该元素没有存在?利用 新数组indexOf(数组元素)如果返回时-1 就说明新数组里面没有改元素
1.封装一个 去重的函数 unique
function unique(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
// 意为 如果查询新数组的返回的是-1 代表没有相同的值
if (newArr.indexOf(arr[i]) === -1) {
// 意为 把当前的元素arr[] 存到push 新数组里
newArr.push(arr[i]);
}
}
return newArr;
}
2.调用上封装好的 unique去重函数
var demo = unique(['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']);
console.log(demo); // 结果为['c', 'a', 'z', 'x', 'b']
数组转换为字符串
方法名 | 说明 | 返回值 |
---|---|---|
toString() | 把数组转换成字符串,逗号分隔每一项 | 返回一个字符串 |
join('分隔符') | 方法用于把数组中的所有元素转换为一个字符串 | 返回一个字符串 |
1.toString() 将我们的的数组转换为字符串
var arr = [1, 2, 3];
console.log(arr.toString()); // 结果为1,2,3
2.join(分隔符)
var arr1 = ['张三', '李四', '王二'];
console.log(arr1.join()); // 结果为 张三,李四,王二
console.log(arr1.join('-')); // 结果为 张三-李四-王二
console.log(arr1.join('·')); // 结果为 张三·李四·王二
console.log(arr1.join('&')); // 结果为 张三&李四&王二
课下查询
slice()和splice()目的基本相同,建议同学们重点看下splice()
方法 | 说明 | 返回值 |
---|---|---|
concat() | 连接两个或多个数组 不影响原数组 | 返回一个新的数组 |
slice() | 数组截取 slice(begin, end) | 返回被截取项目的新数组 |
splice() | 数组删除splice(第几个开始,要删除个数) | 返回被删除项目的新数组 注意,这个会影响原数组 |
字符串对象
基本包装类型
基本包装类型
var str = 'andy';
console.log(str.length); //结果为4
// 对象 才有 属性和方法 复杂数据类型才有 属性和方法
// 简单数据类型为什么会有lenght 属性呢
// 基本包装类型: 就是把简单数据类型 包装成为了 复杂数据类型
(1)把数据类型包装为复杂数据类型
var temp = new String('andy');
(2)把临时变量的值 给 str
str = temp;
(3)销毁这个临时变量
temp = null;
为了方便操作基本数据类型JavaScript还提供了三个特殊的引用类型:String、Number和Boolean。
基本包装类型就是把简单数据类型包装成为复杂数据类型,这样基本数据类型就有了属性和方法。
字符串的不可变
指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。
根据字符返回位置
字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串
方法名 | 说明 |
---|---|
indexOf('要查找的字符',开始的位置) | 返回指定内容在源字符串中的位置,如果找不到就返回-1,开始的位置是index 索引号 |
lastlndexOf() | 从后往前找,只匹配第一个匹配的 |
// 字符串对象 根据字符返回位置 str.indexOf('要查找的字符',[起始的位置])
var str = '改革春风吹满地,春天来了';
console.log(str.indexOf('春')); // 结果是 3
console.log(str.indexOf('春',3)); // 从索引号是3的位置开始往后查找 结果是8
案例:返回字符位置
查找字符串"abcoefxyozzopp"中所有 o 出现的位置以及次数
思路:
- 核心算法:先查找第一个o出现的位置
- 然后 只要indexOf返回的结果不是-1就继续往后查找
- 因为indexOf只能查找到第一个,所以后面的查找,利用第二个参数,当前索引加1,从而继续查找
var str = "abcoefxyozzopp";
var index = str.indexOf('o');
var num = 0;
while (index !== -1) {
console.log(index);
num++;
index = str.indexOf('o', index + 1);
}
console.log('o出现的次数是' + num);
根据位置返回字符(重点⭐⭐)
方法名 | 说明 | 使用 |
---|---|---|
charAt(index) | 返回指定位置的字符(index字符串的索引号) | str.charAt(0) |
charCodeAt(index) | 返回指定位置处的字符的ASCII码(index索引号) | str.charCodeAt(0) |
str[index] | 获取指定位置处字符 | HTML5,IE8+支持和charAt()等效 |
1.charAt(index) 根据位置返回字符
var str = 'andy';
console.log(str.charAt(3)); // 输出索引号3的字符元素 y
// 遍历所有字符 输出所有的字符元素
for (var i = 0; i < str.length; i++) {
console.log(str.charAt(i));
}
2.charCodeAt(index) 返回相应索引号的字符ASCII 目的: 判断用户按下了键盘的哪个键 用于游戏开发
console.log(str.charCodeAt(0)); // 结果为 97
3.str[index] H5新增的根据位置返回字符的方法
var str = 'andy';
console.log(str[0]); // 结果为 a
案例:返回字符位置
判断一个字符串'abcoefxyozzopp'中出现次数最多的字符,并统计其次数
var str = 'abcoefxyozzopp';
var o = {};
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i); // chars 是 字符串的每一个字符
if (o[chars]) { // o[chars] 得到的是属性值
o[chars]++;
} else {
o[chars] = 1;
}
}
console.log(o);
// 遍历对象
var max = 0;
var ch = '';
for (var k in o) {
// k 得到的是属性名
// o[k] 得到的是属性值
if (0[k] > max) {
max = o[k];
ch = k;
}
}
console.log(max);
console.log('最多的字符是' + ch);
拼接以及截取字符串(重点⭐⭐)
1. concat('字符串1','字符串2'...)
var str = 'andy';
console.log(str.concat('red')); //结果为andyred
2. substr('截取的起始位置', '截取几个字符');
var str1 = '改革春风吹满地,春天来了';
console.log(str1.substr('2', '2')); // 结果为 春风 注意:第一个'2'是索引号为2 第二个'2'是截取2个字符
替换字符串以及转换为数组
1.替换字符 replace('被替换的字符', '替换为的字符')
var str = 'andy';
console.log(str.replace('a', 'b')); // 结果是bndy
//如果有多个a呢 只会替换第一个a字符
var str = 'andyandy';
console.log(str.replace('a', 'b')); // 结果是bndyandy
案例:有一个字符串 'abcoefoxyozzopp' 要求把里面所有的 o 替换为 * (将里面所有的o都替换为*)
var str1 = 'abcoefoxyozzopp';
while (str1.indexOf('o') !== -1) {
str1 = str1.replace('o', '*');
}
console.log(str1); // 结果为 abc*ef*xy*zz*pp
2.字符转换为数组 split('分隔符') 前面我们学过 join把数组转换为字符串
var str2 = '张三, 李四, 王二';
console.log(str2.split(',')); // 结果为(3) ['张三', ' 李四', ' 王二']
var str2 = '张三& 李四& 王二';
console.log(str2.split('&')); // 结果为(3) ['张三', ' 李四', ' 王二']
var str2 = '张三% 李四% 王二';
console.log(str2.split('%')); // 结果为(3) ['张三', ' 李四', ' 王二']
课下查阅
- toUpperCase() //转换大写
- toLowerCase() //转换小写
JavaScript 简单类型与复杂类型
简单类型与复杂类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型
- 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型
string , number , boolean , undefined , null - 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型
通过new 关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等
1.简单数据类型 null 返回的是一个空的对象 object
var timer = null;
console.log(typeof timer); // 结果为 object
如果有个变量我们以后打算存储对象,暂时没想好放啥,这个时候就给 null
堆和栈
堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收;复杂数据类型存放到堆里面
注意: JavaScript中没有堆栈的概念,,通过堆栈的方式,可以让大家更容易理解代码的一些执行方式,便于将来学习其他语言。
简单类型的内存分配
- 值类型(简单数据类型): string ,number,boolean,undefined,null
- 值类型变量的数据直接存放在变量(栈空间)中
1.简单数据类型 是存放在栈里面 里面直接开辟一个空间存放的是值
2.复杂数据类型 首先在栈里面存放地址 十六进制表示 然后这个地址指向堆里面的数据
简单数据类型传参
函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。
复杂数据类型传参
函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。
版权声明:本文标题:JavaScript②(数组、函数、作用域、预解析、对象、内置对象、简单类型与复杂类型) 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1725925892a1049359.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论