zoukankan      html  css  js  c++  java
  • 【JavaScript基础】在写冒泡排序时遇到的JavaScript基础问题:JavaScript的数据类型和变量赋值时的原理

    写冒泡排序时,遇到一个问题:

    function bubbleSort(arr){
        var temp = 0;
        console.log("传入的数组:");
        console.log(arr);
        for(var i = 0;i<arr.length;i++){ //循环arr.length-1次
            console.log("外层第"+i+"次循环===============start");
            for(var j = 0;j<arr.length-1;j++){ //循环arr.length-1-1次
                if(arr[j]<arr[j+1]){ //倒叙排列数组:如果相邻的两个,前面那个比后面那个小,就互换
                    temp = arr[j];       // —┐
                    arr[j] = arr[j+1];   // —├—借助中间变量将数组中的两个值进行互换
                    arr[j+1] = temp;     // —┘
                }
                console.log("内层"+j+"次循环");
                console.log(arr);
            }
            console.log("外层第"+i+"次循环===============end");
        }
        return arr;
    }
    var array = [2,3,9,5,7,1,8];
    var sortArray = bubbleSort(array);
    console.log("array   "+array);//array   9,8,7,5,3,2,1
    console.log("sortArray   "+sortArray);//sortArray   9,8,7,5,3,2,1
    //好奇为什么array也被排序了吗?

    看下面的研究:

    我首先想到的是,是不是return的问题。难道我脑子里少记了一个return的不知道的关键作用?

    先测试一下:

    function foo(bar){
       bar = 1;
       return bar;    //return 3;
    }
    var a = 0;
    var b = foo(a);
    console.log(a) //0
    console.log(b) //1  //如果return 3 就得到3
    
    //不加return,
    function foo2(bar2){
    bar2 = 1;
    }
    var a2 = 0;
    var b2 = foo2(a2);
    console.log(a2) //0
    console.log(b2) //undefined
    return就是用来返回函数值的,它真的没什么特殊的神奇的功效。
    其实就是直接删掉return,试一下就知道是不是了,我怎么会怀疑这个。

    等等,为什么上面的a不会被修改掉啊,难道跟a是数字有关?

    那这里的问题应该就出在数组上。

    数组怎么了?关于JavaScript的数据类型和赋值原理的这一块知识,我的脑子里模糊了。

    先来段代码试试:

     function foo(bar){
     bar = [1,2,3,4];
     return bar;
     }
     var a = [1,2,3];
     var b = foo(a);
     console.log(a) //[1,2,3]
     console.log(b) //[1,2,3,4]
    
     function foo2(bar2){
     bar2[0] = 0;
     return bar2;
     }
     var a2 = [1,2,3];
     var b2 = foo(a2);
     console.log(a2) //[0,2,3]
     console.log(b2) //[0,2,3]

    两个函数同样是数组,为什么结果不一样?

    上面原因在于数组是引用数据类型


    关于js数据类型的研究
    js中数据类型分为:
    string,number,boolean,[],{},null,undefined
    字符串,数字,布尔,数组,对象,null,undefined

    null和undefined区别????-------------------------------------undefined:声明变量但未初始化,null,找不到该对象
    null==undefined//true
    null===undefined//false

    上面的数据类型可以分类
    原始类型和引用类型
    原始类型:undefined,null,boolean,number,string
    引用类型:[],{}

    在许多语言中,字符串string都被看作引用类型,而非原始类型,因为字符串的长度是可变的,但是js打破了这一传统。

    但是,JavaScript拥有动态类型的,也就是说,一个变量可以被赋值成不同的类型。

    那么我们接下来就不考虑纠结变量是哪种数据类型了,每个数据类型有怎样怎样了了,我们直接从 变量的值 的角度 来继续思考

    在js中,一个变量可以拥有两种类型的值(参考上面数据类型)
    原始值和引用值
    原始值:存储在栈(stack)中的简单数据段,也就是说,他们的值直接存储在变量访问的位置
    引用值:存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。

    所以,在为变量赋值时,JavaScript的解释程序必须先判断该值是原始类型还是引用类型。
    要实现这一点,JavaScript解释程序则需尝试判断该值是否是JavaScript的原始类型之一。原始类型有哪些上面已经说过了。
    如果是原始类型,由于原始类型占据的空间是固定的,所以在内存中,他们被存储在栈中,这样子便于快速查询变量的值。(关于string长度可变看上面)
    如果是引用类型,那么它的存储空间将从堆中分配。原因是因为,引用值的大小会改变,所以不能把他们放在栈中,否则会降低变量查询的速度。因此我们就把该对象在堆中的地址放在栈中。地址的大小是固定的,所以对变量性能无任何负面影响。
    如图所示:

    
    

    ------------------------------------------------这上面相关知识来源:http://www.w3school.com.cn/js/pro_js_value.asp

    ------------------------------------------------这下面相关知识来源:https://www.zhihu.com/question/26042362/answer/31903017

    所以上面的出现的问题也就好解释了。
    可以简化成这样:

     var a = [1,2,3];
     var b = a;
     a = [4,5,6];
     alert(b);  //[1,2,3]
    
    
     var a = [1,2,3];
     var b = a;
     a.pop();//内置函数,删掉数组最后一个
     alert(b);  //[1,2]

    图解就是这样:

    就算是调用函数
    var b = foo(a)
    只要这个函数里面的操作直接操作传入的数组对象本身,那么就是在操作堆中的对象。
    就会修改到自身。
    只要是没有操作它本身,而是在堆里创建了一个新的对象,然后重新将栈中b的引用地址修改过去。
    就不会修改自身。

    拓展阅读;https://zhuanlan.zhihu.com/p/24080761

  • 相关阅读:
    java基础:11.1 递归
    4.3 Verilog练习(3)
    4.3 verilog中的task用法与例子
    4.3 verilog中的function用法与例子
    4.3 Verilog练习(2)
    4.3 Verilog练习(1)
    4.3 阻塞赋值与非阻塞赋值
    4.2 Vivado Embedded Design (Zynq-7000 series)
    4.1 Vivado使用技巧(3):手把手教你 创建工程,存档工程
    4.1 Vivado使用技巧(2):使用Vivado DocNav
  • 原文地址:https://www.cnblogs.com/ferron/p/6192967.html
Copyright © 2011-2022 走看看