一、概述

1.1、什么是对象

​ 现实生活中:万物皆对象,对象是一个具体的事物,看得见摸得着的实物。例如,一本书、一辆汽车、一个人都是“对象”。

1.2、为什么需要对象

​ 我们知道,JavaScript编程语言,程序开发就是要对现实生活进行模拟,那么在JavaScript中,该如何去描述现实生活中的对象呢?

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

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

  • 属性:事物的特征,在对象中用属性来表示(常用名词)
  • 方法:事物的行为,在对象中用方法来表示(常用动词)

0061

1.3、数组和对象的对比

​ 保存一个值时,可以使用变量,保存多个值(一组值,比如说手机的大小,颜色等)时,可以使用数组。如果要保存一个人的完整信息呢?例如,将”张三疯”的个人的信息保存在数组中的方式为:

0062

​ JS 中的对象表达结构更清晰,更强大。张三疯的个人信息在对象中的表达结构如下:

0063

二、创建对象的方式

2.1、概述

​ 在 JavaScript 中,现阶段我们可以采用三种方式创建对象(object):

  • 字面量方式
  • 利用new Object方式
  • 构造函数方式

2.2、字面量方式

2.2.1、对象定义

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

  • 键:相当于属性名
  • 值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等)
1
2
3
4
5
6
7
8
9
10
11
<script>
var obj = {
username: '张三',
age: 12,
sayHi: function() {
console.log("Hi......");
}
}
// 多个属性或者方法中间用逗号隔开的
// 方法冒号后面跟的是一个匿名函数
</script>

2.2.2、对象调用

  • 对象里面的属性调用 : 对象.属性名 ,这个小点 . 就理解为“ 的
  • 对象里面属性的另一种调用方式 : 对象[‘属性名’]注意方括号里面的属性必须加引号,我们后面会用
  • 对象里面的方法调用:对象.方法名() 注意这个方法名字后面一定加括号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
var obj = {
username: '张三',
age: 12,
sayHi: function() {
console.log("Hi......");
}
}

// 对象的调用
// >> 1、对属性的调用
// >>>> 1.1 方式一: 对象.属性名
console.log(obj.username);

// >>>> 1.2 方式二: 对象['属性名']
console.log(obj['age']);


// >> 2、对方法的调用. 对象名.方法名()
obj.sayHi();
</script>

2.3、new Object方式

2.3.1、案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
var obj = new Object();

// >> 添加属性
obj.username = "张三丰";
obj['age'] = 23;

// >> 添加方法
obj.sayHi = function() {
console.log("Hi");
}

// 对象调用
// 属性
console.log(obj['username']);
console.log(obj.age);
// 方法
obj.sayHi();
</script>

2.3.2、注意点

  • Object() :第一个字母大写
  • new Object() :需要 new 关键字
  • 使用的格式:对象.属性 = 值;

2.4、构造函数方式

2.4.1、为什么需要构造函数方式

1
# 原因: 就是因为我们前面两种创建对象的方式一次只能创建一个对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script>
// 定义张三对象
var zhangsan = {
username: '张三',
age: 34,
eat: function() {
console.log('吃饭');
}
}

// 定义李四对象
var lisi = {
username: 'lisi',
age: 23,
eat: function() {
console.log('吃饭');
}
}

/***
* 1、因为我们一次创建一个对象,里面很多的属性和方法是大量相同的 我们只能复制,存在冗余
* 2、我们可以利用函数的方式 重复这些相同的代码 我们就把这个函数称为 构造函数
* (因为之前在讲函数的时候,函数的作用就是可以重复利用代码)
* 3、为什么又要叫构造函数呢?
* 因为此函数和之前学习的函数不一样,这里的函数里面封装的不是普通代码,而是对象(相同的属性和方法)
* 4、总结
* 构造函数 就是把我们对象里面一些相同的属性和方法抽象出来封装到函数里面
* /
</script>

2.4.2、利用构造函数创建对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
// 定义构造函数(是一类对象,都具有相同的属性和方法)
function Person(username, age, sex) {
this.username = username;
this.age = age;
this.sex = sex;
this.sayHi = function() {
alert('名字叫:' + this.username + ',年龄:' + this.age + ',性别:' + this.sex);
}
}

// 通过构造函数创建对象
// >> 创建张三
var zhangsan = new Person("张三", 10, "男");
console.log(zhangsan.username);
console.log(zhangsan['sex']);
zhangsan.sayHi();

// >> 创建李四
var lisi = new Person("李四", 20, "女");
console.log(lisi.username);
console.log(lisi['sex']);
lisi.sayHi();
</script>

注意

  1. 构造函数约定首字母大写。

  2. 函数内的属性和方法前面需要添加 this ,表示当前对象的属性和方法。

  3. 构造函数中不需要 return 返回结果,其实当我们new的时候,函数已经将当前的this进行了return。

  4. 当我们创建对象的时候,必须用 new 来调用构造函数。

2.4.3、总结

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

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

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

2.4.5、构造函数和对象的区别

  • 构造函数,如 Person(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class)
  • 对象,如 new Person(),特指某一个,通过 new 关键字创建对象的过程我们也称为对象实例化

0064

2.4.6、new 关键字的执行过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script>
// 定义构造函数(是一类对象,都具有相同的属性和方法)
function Person(username, age, sex) {
this.username = username;
this.age = age;
this.sex = sex;
this.sayHi = function() {
alert('我的名字叫:' + this.username + ',年龄:' + this.age + ',性别:' + this.sex);
}
}

// 通过构造函数创建对象
/**
new 关键字执行过程:
1、 首先 new 构造函数在内存中创建了一个空的对象
2、 this 就会指向刚才创建的空对象
3、 执行构造函数里面的代码 给这个空对象添加属性和方法
4、 返回这个对象
5、 将这个对象的内存地址赋值给var声明的变量
*/
var zhangsan = new Person("张三", 10, "男");
console.log(zhangsan.username);
console.log(zhangsan['sex']);
zhangsan.sayHi();
</script>

2.5、遍历对象属性

2.5.1、说明

​ for…in 语句用于对数组或者对象的属性进行循环操作。

​ 语法:

0065

2.5.2、案例

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
// 定义对象
var person = {
username: 'HelloWorld',
age: 10,
sex: '男'
};

// 遍历对象
for (var key in person) {
console.log(key + ":" + person[key]);
}
</script>

2.6、小结

  1. 对象可以让代码结构更清晰

  2. 对象是复杂数据类型object。

  3. 本质:对象就是一组无序的相关属性和方法的集合。

  4. 构造函数泛指某一大类,比如苹果,不管是红色苹果还是绿色苹果,都统称为苹果。

  5. 对象实例特指一个事物,比如这个苹果、正在路上飞奔的那辆红色轿车等。

  6. for…in 语句用于对对象的属性进行循环操作。

三、内置对象

3.1、说明

  • JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象
  • 前面两种对象是JS 基础 内容,属于 ECMAScript; 第三个浏览器对象属于我们JS 独有的, 后面讲
  • 内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
  • 内置对象最大的优点就是帮助我们快速开发
  • JavaScript 提供了多个内置对象:Math、 Date 、Array、String等

0066

3.2、Math对象

3.2.1、说明

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

3.2.2、最大值

1
2
3
4
5
<script>
console.log(Math.PI); // 3.1415926
console.log(Math.max(10, 23, 18)); // 23
console.log(Math.max(1, 2, 'abc')); // NaN
</script>

3.2.3、绝对值

1
2
3
4
5
6
<script>
console.log(Math.abs(-10)); // 10
console.log(Math.abs(10)); // 10
console.log(Math.abs('-20')); // 20,会把字符串'-20'隐式转换为数字类型
console.log(Math.abs('abc')); // NaN
</script>

3.2.4、取整

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
// 3个取整方法
// >> Math.floor() 向下取整,往最小了取值
console.log(Math.floor(1.1)); // 1
console.log(Math.floor(1.9)); // 1
console.log(Math.floor(-1.1)); // -2
console.log(Math.floor(-1.9)); // -2

// >> Math.ceil() 向上取整 往最大了取值
console.log(Math.ceil(1.1)); // 2
console.log(Math.ceil(1.9)); // 2
console.log(Math.ceil(-1.1)); // -1
console.log(Math.ceil(-1.9)); // -1

// >> Math.round() 四舍五入
console.log(Math.round(1.1)); // 1
console.log(Math.round(1.9)); // 2
console.log(Math.round(-1.1)); // -1
console.log(Math.round(-1.9)); // -2

// 特殊: 其他数字都是四舍五入,但是 .5 特殊 它往大了取
console.log(Math.round(-1.5)); // 这个结果是 -1
</script>

3.2.5、随机数

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

​ 得到一个两数之间的随机整数,包括两个数在内:

0067

1
2
3
4
5
6
7
8
9
10
11
<script>
/*
两个数之间的随机整数 并且 包含这2个整数:
Math.floor(Math.random() * (max - min + 1)) + min;
*/
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

console.log(getRandom(2, 13));
</script>
1
2
3
4
5
6
7
8
9
10
<script>
// 两个数之间的随机整数 并且 包含这2个整数:
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

// 随机点名
var arrs = ['张三', '李四', '王五', '赵六', '麻七'];
console.log(arrs[getRandom(0, arrs.length - 1)]);
</script>

3.3、日期对象

3.3.1、说明

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

3.3.2、方法的使用

1
2
3
4
5
<script>
// 如果没有参数 返回当前系统的当前时间
var date = new Date();
console.log(date);
</script>
1
2
3
4
5
<script>
// 数字型参数 2021, 10, 01
var date = new Date(2021, 10, 8);
console.log(date); // 注意:返回的是11月
</script>
1
2
3
4
5
<script>
// 数字型参数 2021, 10, 01
var date = new Date('2021-10-08 12:12:12');
console.log(date); // 注意:返回的是11月
</script>
  • 如果Date()不写参数,就返回当前时间
  • 如果Date()里面写参数,就返回括号里面输入的时间

3.3.3、日期格式化

0068

1
2
3
4
5
6
7
<script>
var date = new Date();
console.log(date.getFullYear()); // 返回当前的年
console.log(date.getMonth() + 1); // 月份 返回的月份小1个月,记得月份+1
console.log(date.getDate()); // 返回的是几号
console.log(date.getDay()); // 返回的是周几
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
// 需求:格式化日期,得到 2021年10月09日 星期三
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
var day = date.getDay();
var arrs = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];

// 拼接
var result = year + "年 " + month + " 月 " + dates + " 日 " + arrs[day];

console.log(result);
</script>
1
2
3
4
5
6
7
<script>
// 获取时分秒
var date = new Date();
console.log(date.getHours()); // 小时
console.log(date.getMinutes()); // 分
console.log(date.getSeconds()); // 秒
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
// 需求: 封装一个函数,返回当前的时分秒
function getTime() {
var date = new Date();
var h = date.getHours();
h = h < 10 ? '0' + h : h;
var m = date.getMinutes();
m = m < 10 ? '0' + m : m;
var s = date.getSeconds();
s = s < 10 ? '0' + s : s;

return h + ":" + m + ":" + s;
}

console.log(getTime());
</script>

3.3.4、获取毫秒数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
// 获取距离1970年1月1日到现在为止总的毫秒数
var date = new Date();

// >> 方式一
console.log(date.valueOf());

// >> 方式二
console.log(date.getTime());

// >> 方式三
var date1 = +new Date();
console.log(date1);

// >> 方式四【H5新增的】
console.log(Date.now());
</script>

3.3.5、案例

​ 倒计时效果。

0069

1
2
3
4
5
6
7
8
9
# 思路
1. 输入的时间减去现在的时间就是剩余的时间,即倒计时 ,但是不能拿着时分秒相减,比如 05 分减去25分,结果会是负数的。
2. 用时间戳来做。用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数。
3. 把剩余时间总的毫秒数转换为天、时、分、秒 (时间戳转换为时分秒)
4. 转换公式如下:
d = parseInt(总秒数/ 60/60 /24); // 计算天数
h = parseInt(总秒数/ 60/60 %24) // 计算小时
m = parseInt(总秒数 /60 %60 ); // 计算分数
s = parseInt(总秒数%60); // 计算当前秒数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
// 倒计时
function timeDown(time) {
var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
var inputTime = +new Date(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(timeDown('2021-10-09 17:53:00'));
</script>

3.4、数组对象

3.4.1、检测一个对象是否是数组类型

  • instanceof 运算符,可以判断一个对象是否属于某种类型
  • Array.isArray()用于判断一个对象是否为数组,isArray() 是 HTML5 中提供的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
// 检测是否为数组
var arrs = [];
var obj = {};

// 方式一: instanceof 运算符
console.log(arrs instanceof Array); // true
console.log(obj instanceof Array); // false

// 方式二:Array.isArray(参数); H5新增的方法 ie9以上版本支持
console.log(Array.isArray(arrs)); // true
console.log(Array.isArray(obj)); // false
</script>

3.4.2、添加删除数组元素的方法

0070

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 <script>
// 添加删除数组元素的方法
var arrs = [1, 2, 3, 4];

// >> push() 在我们数组的末尾 添加一个或者多个数组元素,返回数组的长度
console.log(arrs.push(5, 'Hello'));
console.log(arrs);

// >> unshift() 在数组的开头 添加一个或者多个数组元素,返回数组的长度
console.log(arrs.unshift('javascript'));
console.log(arrs);

// >> pop() 删除数组的最后一个元素,一次只能删除一个元素,返回的是被删除的元素
console.log(arrs.pop());
console.log(arrs);

// >> shift() 删除数组的第一个元素,一次只能删除一个元素, 返回的是被删除的元素
console.log(arrs.shift());
console.log(arrs);
</script>

3.4.3、数组排序的方法

0071

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
// 数组排序
// >> reverse() 翻转数组
var arrs = [1, 2, 3, 4, 5];
arrs.reverse();
console.log(arrs);

// >> sort() 排序
var arrs2 = [11, 3, 21, 16, 34, 1];
arrs2.sort(function(a, b) { // 自定义排序
return a - b;
});
console.log(arrs2);
</script>

3.4.4、数组索引的方法

0072

1
2
3
4
5
6
7
8
9
10
11
<script>
// 返回数组元素索引号的方法
// >> indexOf(数组元素) 作用就是返回该数组元素的索引号 从前面开始查找
// 注1:它只返回第一个满足条件的索引号
// 注2:如果在该数组里面找不到元素,则返回的是 -1
var arrs = ['HTML', 'CSS', 'JavaScript', 'Hello', 'CSS'];
console.log(arrs.indexOf('CSS'));

// >> lastIndexOf(数组元素) 作用就是返回该数组元素的索引号 从后面开始查找
console.log(arrs.lastIndexOf('CSS'));
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script>
// 数组去重 ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'] 要求去除数组中重复的元素。
/**
* 目标:
* 把旧数组里面不重复的元素选取出来放到新数组中, 重复的元素只保留一个, 放到新数组中去重。
* 算法:
* 我们遍历旧数组, 然后拿着旧数组元素去查询新数组, 如果该元素在新数组里面没有出现过, 我们就添 加, 否则不添加。
* 我们怎么知道该元素没有存在?
* 利用 新数组.indexOf(数组元素) 如果返回时 - 1 就说明 新数组里面没有改元素、
*/

function getUnique(arrs) {
var newArrs = [];
for (var i = 0; i < arrs.length; i++) {
if (newArrs.indexOf(arrs[i]) === -1) {
// 表示不存在
newArrs.push(arrs[i]);
}
}
return newArrs;
}
var arrs = ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'];
var result = getUnique(arrs);
console.log(result);
</script>

3.4.5、数组转换为字符串

0073

1
2
3
4
5
6
7
8
9
10
<script>
// 数组转换为字符串
// >> toString() 将数组转换为字符串,数组元素用逗号分隔
var arrs = [1, 2, 3];
console.log(arrs.toString());

// >> join(分隔符) 将数组元素按照指定的分隔符进行连接
var result = arrs.join('_');
console.log(result);
</script>

3.4.6、数组的其他方法

0074

1
2
3
4
5
6
7
8
9
<script>
// 数组的其他方法: 连接
// >> concat() 连接两个或多个数组, 方法不会更改现有数组,而是返回一个新数组
var arrs1 = [1, 2, 3];
var arrs2 = [4, 5, 6];
var arrs3 = [7, 8, 9];
var result = arrs1.concat(arrs2, arrs3);
console.log(result);
</script>
1
2
3
4
5
6
7
8
<script>
// 数组的其他方法: 截取
// >> slice(start,end) 从给定的start参数开始的元素,并在给定的end参数处结束(不包括end)
var arrs = [1, 2, 3, 'Java', 'Hello', 'js', 7, 9];
var result = arrs.slice(2, 5);
console.log(arrs);
console.log(result);
</script>
1
2
3
4
5
6
7
8
<script>
// 数组的其他方法: 截取
// >> splice(index, howmany) 从数组指定位置删除指定个数的元素,并返回删除的元素。
var arrs = [1, 2, 3, 'Java', 'Hello', 'js', 7, 9];
var result = arrs.splice(2, 5);
console.log(arrs); // [1, 2, 9] 删除,会影响原数组
console.log(result); // [3, 'Java', 'Hello', 'js', 7]
</script>

3.5、字符串对象

3.5.1、根据字符返回位置

​ 字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串。

0075

1
2
3
4
5
6
<script>
// 字符串对象 根据字符返回位置 str.indexOf('要查找的字符', [起始的位置])
var str = '改革春风吹满地,春天来了';
console.log(str.indexOf('春'));
console.log(str.indexOf('春', 3)); // 从索引号是 3的位置开始往后查找
</script>

3.5.2、根据位置返回字符

0076

1
2
3
4
5
6
7
8
9
10
11
12
<script>
// 根据位置返回字符
// 1. charAt(index) 根据位置返回字符
var str = 'JavaScript';
console.log(str.charAt(3));

// 2. charCodeAt(index) 返回相应索引号的字符ASCII值 目的: 判断用户按下了那个键
console.log(str.charCodeAt(1)); // 97

// 3. str[index] H5 新增的
console.log(str[6]);
</script>

3.5.3、字符串的其他方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
// 字符串的其他方法
// 1. substr('截取的起始位置', '截取几个字符');
var str = 'JavaScript';
console.log(str.substr(3, 6));

// 2. substring('截取的起始位置', '截取的结束位置');
console.log(str.substring(3, 6));

// 3. replace('被替换的字符', '替换为的字符') 它只会替换第一个字符,返回新的字符串
console.log(str.replace('a', 'A'));

// 4. split('分隔符') 返回的结果是一个数组
var str2 = 'Hello,java,Spring';
var arrs = str2.split(',')
console.log(arrs);
</script>

四、简单类型与复杂类型

4.1、概述

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

  • 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型

    ​ string ,number,boolean,undefined,null

  • 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型

    ​ 通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等

4.2、堆和栈

​ 堆栈空间分配区别:

  1、栈:存储的是函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;

简单数据类型存放到栈里面

​ 2、堆:存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。

复杂数据类型存放到堆里面

0077

4.3、简单类型的内存分配

  • 值类型(简单数据类型): string ,number,boolean,undefined,null
  • 值类型变量的数据直接存放在变量(栈空间)中

0078

4.4、复杂类型的内存分配

  • 引用类型(复杂数据类型):通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
  • 引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中

0079

4.5、简单数据类型传参

​ 函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。

1
2
3
4
5
6
7
8
9
10
11
<script>
var x = 10;

function fn(a) {
a++;
console.log(a); // 11
}

fn(x);
console.log(x); // 10
</script>

0080

4.6、复杂数据类型传参

​ 函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
function Person(name) {
this.name = name;
}

function f1(x) {
console.log(x.name);
x.name = "张学友";
console.log(x.name);
}

var p = new Person("刘德华");
console.log(p.name);
f1(p);
console.log(p.name);
</script>

0081