【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

时间: 2024-12-13 15:26:47

【JavaScript基础】在写冒泡排序时遇到的JavaScript基础问题:JavaScript的数据类型和变量赋值时的原理的相关文章

String在方法中的传递方式(调用外部方法给String变量赋值时,未得到预期结果)

示例: public class StringTraining { public static void changeStr(String str){ str = "137878"; } public static void main(String[] args){ String a = "b"; changeStr(a); System.out.println(a); }} 输出仍旧为b 分析:首先栈中存的是堆中对象的地址,因为String对象的特殊性(Strin

关于&quot;&amp;&quot;操作符在变量赋值时的使用

//声明变量a,并赋值为123$a = "123"; //打印变量a的值为123var_dump($a); //声明变量b,并将变量a的引用(地址)指向变量b$b = &$a; //打印变量b的值为123var_dump($b); //修改变量b的值$b= "abc"; //打印变量b的值为abcvar_dump($b); //打印变量a的值为abcvar_dump($a); //说明:"&"操作符是将变量a的引用(地址)指向给变

【python】字符串变量赋值时字符串可用单或双引号

1 >>> name='萧峰' 2 >>> print(name) 3 萧峰 4 >>> name="独孤求败" 5 >>> print(name) 6 独孤求败 7 >>>

Python入门(二)——IDE选择PyCharm,输入和输出,基础规范,数据类型和变量,常量,字符串和编码,格式化

Python入门(二)--IDE选择PyCharm,输入和输出,基础规范,数据类型和变量,常量,字符串和编码,格式化 我们从今天就开始正式的学习PY交易了,PY交易还行,我们有基础之后学习起来倒不是说那么的被动,我学习的是Python2.7,虽然现在随着版本的迁移至Python3,但是这个并不会对我们造成什么困扰,毕竟只是一个适应阶段 我们的学习资料:廖雪峰官方网站Python2.7教程 一.IDE选择PyCharm 我们虽然在前面一章已经配置过,但是我们还是有很多的IDE可以开发Py,比如su

[JS] 让人犯晕的JavaScript变量赋值

变量赋值 本文转载自http://hellobug.github.io/blog/javascript-variable-assignment/ 开始之前先来几个例子,确保起始点是晕的状态- :P 例1.1 1 2 3 4 var a = "apple"; var b = a; a = "banana"; b 按理说,b = a后,a是啥值b就应该跟着是啥值了~但,b结果是"apple",还是一开始赋值时a的值. 例1.2 1 2 3 4 var

玩转 React(三)- JavaScript代码里写HTML一样可以很优雅

这是<玩转 React>系列的第三篇,看到本篇的标题,了解过 React 的同学可能已经大致猜到我要讲什么了,本篇中要讲的内容对于刚接触 React 的同学来说,可能有些难以接受,但希望你能坚持学下去,这是 Facebook 的前端大神们为前端开发做出的革命性创新. React 第一印象 废话不多说,先看一段代码: class HelloMessage extends React.Component { render() { return <div>Hello {this.prop

JavaScript与html5写的贪吃蛇完整代码

JavaScript与html5写的贪吃蛇完整代码 查看运行效果可访问http://www.codesocang.com/texiao/youxitexiao/2014/0402/7045.html# <!doctype html><html lang="en"><head><meta charset="utf-8"><title>js网页版的贪吃蛇游戏</title><style typ

我的javascript学习之路(一)对象之基础

做了2个多月的ajax项目,对js的学习觉得了深入了不少,把自己的一些学习的经验贴出来,希望对初学者有所帮助,也希望大家能指出我的错误之处或者不当之处. javascript 是基于对象的语言,为什么这么说呢,需要仔细思考. js的单根继承体系需要仔细了解,我觉得在js的世界里本身没有类的概念,他只有对象Object,不像java语言本身就有了Object然后又有Class,js中我们可以自己根据他的语言来构件类这一对象,因为没有语言本身的支持,所以方法就各种各样了,但是只要我们掌握了js的本质

javascript入门视频第一天 小案例制作 零基础开始学习javascript

JavaScript 是我们网页设计师必备的技能之一.我们主要用javascript来写的是网页特效.我们从零基础开始学习javascript入门. 但是,好的同学刚开始不知道怎么学习,接触js,因此,小强老师给大家写了这篇入门的javascript文章.从零基础开始学习js,使大家入门更简单,希望大家喜欢.JavaScript是一种脚本语言. 也是我们web网络中最为流行一种脚本语言.脚本语言:     1.不是独立存在的.需要依附.js就是依附在浏览器中.     2.脚本语言也是语言,也有