JavaScript变量和内存(参数按值传递解惑)

JavaScript变量包含两种不同类型的变量值:基本类型和引用类型!
基本类型:
保存在栈内存中的简单数据段,即这种值完全保存在内存中的一个位置。


引用类型:
变量中实际保存只是一个指向保存对象的一个指针;


将一个值赋给变量的时候,解析器必须确定这个值是基本类型值,还是引用类型值。基本类型值:Undefinded , Null, Boolean,
Number, String.这些类型在内存中分别占有固定大小的空间,他们的值保存在栈空间,通过按值访问的。
如果赋值是引用类型的,则必须在内存中为这个值分配空间,由于这种值的大小不固定,因此不能保存在栈内存中,但内存地址大小是固定的,所以可以把内存地址保存在栈内存中,这样,当查询引用类型的变量时,先从栈中读取内存地址,然后通过地址找到堆中的值,这种叫做按引用访问。


引用值的大小会改变,所以不能把它放在栈中,否则会降低变量查寻的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响。

在ECMAScript中是不允许直接访问保存在堆内存中的对象的,所以在访问一个对象时,首先得到的是这个对象在堆内存中的地址,然后再按照这个地址去获得这个对象中的值,这就是按引用访问。而原始类型的值则是可以直接访问到的。

这里写图片描述


var box = new Object();  //var box = {};
box.name = 'lee';
alert(box.name);


var box = 'Lee'; //基本类型值,是字符串
box.age = 29;
alert(box.age);//不是引用类型,无法输出,结果为undefined

复制变量值
复制变量值这方面,基本类型和引用类型不同,基本类型复制的是值本身,而引用类型复制的是地址

var box = 'Lee';//栈内存生成一个box ‘Lee’
var box2 = box;//栈内存再生成一个box2 ‘Lee’
//box2虽然是box的一个副本,但是,两者完全独立,这两个变量分开操作互不影响
//只是把变量里的值传递给参数,之后参数和这个变量互不影响

这里写图片描述


var box = new Object();
box.name = 'lee';
var box2 = box;//复制的是地址
box2.name = 'guoyu';
alert(box.name);//guoyu

这里写图片描述


传递参数

JavaScript中所有函数的参数都是按值传递的,参数不会按引用传递,

function box(num) {
    num += 10;
    return num;
}
//num这里是按值传递,传到box()里,又是一个全新的副本,跟原来的实参没关系
var num = 50;
alert(box(num));//60
alert(num);//50
//假设是按照引用传递,那么函数里的num会成为类似全局变量,最后原件num也是60了

JS没有按引用传参的功能,不能把传递引用类型的参数当做按引用传参
JS没有按引用传参的功能,不能把传递引用类型的参数当做按引用传参
JS没有按引用传参的功能,不能把传递引用类型的参数当做按引用传参

function box(obj) {//传递一个引用类型参数,但不是按照引用传递,是按值传递
    obj.name = 'Lee';
}

var obj = new Object();
box(obj);
alert(obj.name);//Lee
//奇怪,为什么能打印出Lee?

其实传的是对象的地址,这个地址也是一个值啊,js只按值传递,这里的值是地址,地址也是个值,(不是对象本身的值),但是我们可以通过地址的值来操作真实的对象。参考C++指针,多个地址指向同一块内存, *p1 , *p2等都可以操作这块内存。

再看一个例子

function setName(obj) {
    obj.name = 'aaa';
    var obj = new Object(); // 如果是按引用传递的,此处传参进来obj应该被重新引用新的内存单元
    obj.name = 'ccc';
    return obj;
}

var person = new Object();
person.name = 'bbb';
var newPerson = setName(person);
console.log(person.name + ' | ' + newPerson.name); // aaa | ccc
function Box() {
    var obj = new Object();
    obj.name = 'guoyu';
    return obj;
}

var b = Box();
alert(b.name);//guoyu
//类似工厂模式
var a = {
    num:'1'
};

var b = {
    num:'2'
};

function change(obj){
    obj.num = '3';
    obj = b;
    return obj.num;
}

var result = change(a);
console.log(result + ' | ' + a.num); // 2 | 3 

在网上还看到一种叫 按共享传递 的说法,而且特别好理解。
大致概念是这样的:调用函数传参时,函数接受对象实参引用的副本(既不是按值传递的对象副本,也不是按引用传递的隐式引用)。
它和按引用传递的不同在于:在共享传递中对函数形参的赋值,不会影响实参的值。
切记:地址也是值,参数是对象时,JS是按照地址值传递的,也就是将对象的实际地址复制一份给形参,形参也指向了实际的对象,你怎么操作形参(地址),并不影响原先的地址。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java变量JavaScript变量之间的传递是不直接的,因为它们属于不同的编程语言。 Java是一种静态类型语言,变量必须先声明并指定类型,然后才能使用。Java变量的作用范围通常在声明它们的代码块中有效,并且可以通过传递参数或返回的方式在不同的方法之间传递。 而JavaScript是一种动态类型语言,变量的类型是根据赋给它们的来确定的。JavaScript变量的作用范围通常是定义它们的函数中,并且可以通过函数参数、全局变量或者通过DOM进行传递和访问。 如果需要在Java和JavaScript之间进行数据传递,需要使用一些中间的方式。一种常用的方法是使用HTTP请求和响应,通过前端发送HTTP请求到后端Java服务器,后端处理请求并返回数据给前端JavaScript进行处理和展示。 另一种方法是使用WebSocket技术,在Java服务器上建立WebSocket连接,并使用JavaScript API与服务器进行实时双向通信。 除了以上方法,还可以使用其他跨语言的技术,如JSON、XML等,通过串行化和反串行化将数据从一种语言转换为另一种语言进行传递。 总之,Java变量JavaScript变量之间的传递需要借助中间的技术和方法进行交互和转换,以实现数据的传递和共享。 ### 回答2: Java变量JavaScript变量是两种不同的编程语言中的概念,它们之间的传递需要通过特定的方式进行。 首先,Java是一种静态类型语言,变量在声明时需要指定其类型,并且在编译时会进行类型检查。而JavaScript是一种动态类型语言,变量不需要指定类型,并且在运行时可以根据赋的内容自动进行类型推断。这意味着Java变量JavaScript变量在声明和使用上存在一些不同之处。 如果需要在Java和JavaScript之间进行变量传递,可以通过以下几种方式实现: 1. 通过Web API进行传递:可以使用Java后端与JavaScript前端之间的Web API进行变量传递。通过HTTP请求,在Java后端获取数据后,将其通过JSON格式返回给前端JavaScript进行处理和显示。 2. 使用JavaScirpt引擎调用Java代码:Java提供了JavaScript引擎,可以通过该引擎在Java中直接执行JavaScript代码。这样可以在Java中调用JavaScript函数,将Java变量作为参数传递JavaScript函数,或者通过JavaScript函数的返回获取JavaScript变量。 3. 使用Java和JavaScript的互操作库:有些互操作库可以让Java和JavaScript代码更容易地进行集成。例如,Rhino是一个开源的Java与JavaScript互操作库,可以在Java中直接调用JavaScript函数,并传递变量。 需要注意的是,由于Java和JavaScript是两种不同的编程语言,它们之间的变量传递通常需要特定的桥接机制或者接口来实现。在设计和开发过程中,需要仔细考虑变量的类型、数据格式和有效性,以确保正确地进行变量传递和处理。 ### 回答3: Java和JavaScript是两种不同的编程语言,它们之间的变量传递方式也有一些不同。 首先,Java是一种静态类型语言,而JavaScript是一种动态类型语言。这意味着在Java中,在使用变量之前必须先声明变量的类型,并且变量的类型在编译时确定。而JavaScript中的变量是可以随时改变类型的。 其次,Java通过使用参数传递的方式来传递变量参数分为传递和引用传递两种情况。在传递中,将变量复制一份传递给函数,对这份复制的进行修改不会影响原始变量。而在引用传递中,将变量的地址传递给函数,对这个地址指向的变量进行修改会影响原始变量。 而JavaScript中只有传递一种方式。因为JavaScript中的变量是动态类型的,函数的参数只是存储了变量,而不会存储变量的引用。当将一个变量作为参数传递给函数时,函数会创建一个新的变量,将原始变量复制过去。 总的来说,Java和JavaScript之间的变量传递方式有一些差异。Java是静态类型语言,使用参数传递的方式传递变量,可以区分传递和引用传递。而JavaScript是动态类型语言,只有传递一种方式,将变量复制给函数的参数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值