javascript 数据类型在内存中存储的方式 (简单类型,复杂类型,简单、复杂作为函数在内存的方式,数组的特点)

js 中数据类型中包含:

基本数据类型:String、Boolean、Number、undefined、null、Symbol
引用数据类型(复杂数据类型):Object

1. 简单类型作为参数在内存中存储的方式

如代码:var n1 = 10; var n2 = n1
求 如果n1 里面的值发生变化时,n2 是否有影响
过程如图所示:
在这里插入图片描述

1 . 访问n1时 在栈内存开辟一个空间,定义为10,到时访问变量n1时,就会直接调取空间的值。
2 . 访问n2时,也是需要在内存中开辟一个空间,存储值为10,相当于复制了一份n1,如果n1改变值时,n2不会影响。

2. 复杂类型作为参数在内存中存储的方式

// 复杂类型 : Object 所有对象都是复杂类型 (所有的对象都是基于Object)
定义一个自定义构造函数,

function Person(name, age, sayHi) {
        this.name = name;
        this.age = age;
        this.sayHi = function () {
            console.log(this.name + 'hello');
        }
     }
     var p1 = new Person('zs', 18);
    var p2 = p1;
    console.log(p2);
// 求 如果p1 里面的值发生变化时,p2 是否有影响
	

在这里插入图片描述

复杂类型:只有在新建一个对象时,才会在内存存储对象。此时在内存中新建了一个p1的对象,里 面包含所有属性,方法。
访问变量p1时,会先在栈上访问内存地址,再访问内存地址指向的对象属性,
如果访问p2时,因p2等于p1,所以两个内存地址一样的,所以在堆上不会新建对象,
直接访问p1的对象属性,如p1对象属性发生变化时,p2也会随之发生变化。

3. 简单类型作为函数参数在内存中存储的方式

function fn(a, b) {
            a = a+1;
            b = b+1;
            console.log(a);
            console.log(b);
        }
        var x = 10;
        var y = 20;
        fn(x, y);
        console.log(x);
        console.log(y);
        // 求: 在函数内部对 a 和 b 的值进行修改,那么函数外部是否会影响 x 和 y 的值。、

在这里插入图片描述

简单类型作为函数:首先,function fn (a,b)到函数内部没有调用,所以内存不会运行,
当函数调用时,内存才会运行,所以先运行x y的运算。当:x=10, y=20时,会在内存栈开辟一个空间,存
储x和y的值。再把函数的实参传给形参,a和b,当函数内存a和b发生变化时:a+1 (10+1),
b+1 (20+1),那么在内存另外开辟一个空间,分别存a和b 的值,然后再打印a 和b改变后的值,
然后函数fn(x,y)执行完毕。函数执行完毕后,再打印x 和y 的值。所以x和y值不会受函数内部变化而影响。

4. 复杂类型作为函数参数在内存中存储的方式

function Person(name, age) {
          this.name = name;
          this.age = age;
          this.sayHi = function () {
              console.log(this.name + '--hello')
          }
        }
        var p = new Person('zs', 18);
        function fn(person) {
            person.name = 'ls';
            // 假如person = new person ,重新赋值
            person = new Person('ww' ,20);
            console.log(person.name);
         //   此时求 person的name?
       /* 2.  因为 person 重新创建了一个对象,所以在堆上会重新建立一个名为person的对象,里面属性包含 ww 和20
            再在栈上开辟一个空间,存储person的内存地址,此时,p的内存地址和person的内存地址不同 ,指向了不同的对象,
            所以上面求的person.name的结果为:ww 。p 的结果为ls  */

        }
        fn(p);
        console.log(p.name);

        // 求:最后打印的p.name 的值为?

在这里插入图片描述

  1. 运算过程:在堆里内存里创建一个p的对象,里面包含name, age,再在栈中开辟一个空间,
    存储变量p的内存地址。访问变量p时,首先访问栈上的地址,再通过廾上的地址可以访问堆内存的对象里面的所有属性。
    往下:声明了一个函数,name= ls.再调用函数,p为实参,把实参赋值给形参(function fn (person))
    部分没有new关键字,所以不会在堆上开辟新的对象, p为实参,把实参赋值给形参,把p的值赋值给person,
    所以person的内存地址就是P的地址。指向同一个对象,如果函数内部改变name的属性,
    因为p和person指向的是同一个对象,所以p.name 也会随之改变。

5.数组作为参数在内存中存储的方式

数组也是复杂类型。
冒泡排序(从小排到大),数组作为函数参数的特点

function sort (arry) {
// 外层循环,控制趟数
	for (var i = 0; i < arry.length-1; i++ ) {
// 假设排序好了
	var isSort = true;
// 内层循环,控制两两比较的次数
	for (var j = 0; j < arry.length -1 -i; j++) {
		if (arry [j] > arry [j+1]) {
		isSort = false;
		// 如果没排序好,两个交换位置
		//如果前一个数 大于 后一个数,将前一个的值存在temp中,后一个的值赋值给前一个位置,
	//	然后将temp中的前一个赋值给后一个	
	var tmp = arry[j];
	arry[j] = arry [j+1];
	arry [j+1] = tmp;

}
// 判断是否排序好 
	if (isSort) {
		break;
	}
}
	return arry;
}
// 定义一组数组
var arry = [3, 40, 5, 3, 90, 47];
function fn (arr) {
	arr[0] = -5;
}
fn(arry);
sort(arry);
console.loe(arry);

// 求,如果改变arr函数的第一个下标,最后arry的值是否会受影响?

在这里插入图片描述

运算过程:在堆里内存里创建一个arry的对象,里面包含下标0-3的值的属性,,再在栈中开辟一个空间,
存储变量arry的内存地址。访问变量arry时,首先访问栈上的地址,再通过廾上的地址可以访问堆内存的对象里面的所有属性。
往下:声明了一个函数,调用函数,让arry的实参传给fn 的形参。相当于复制了一份arry变量,栈上的内存地址一样,
两个指向的是同一个对象,让函数的第一个下标值等于 -1,因为两个指向了同一个对象,所以arry的属性结果也会受影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值