`

JS 传值与传址

 
阅读更多
在 JScript 中,对数据的处理取决于该数据的类型。

按值和按引用的比较

Numbers 和 Boolean 类型的值 (true 和 false) 是按值来复制、传递和比较的。
当按值复制或传递时,将在计算机内存中分配一块空间并将原值复制到其中。然后,即使更改原来的值,也不会影响所复制的值(反 过来也一样),因为这两个值是独立的实体。

对象、数组以及函数是按引用(即地址)来复制、传递和比较的。
当按地址复制或传递时,实际是创建一个指向原始项的指针,然后就像拷贝一样来使用该指针。如果随后更改 原始项,则将同时更改原始项和复制项(反过来也一样)。实际上只有一个实体;“复本”并不是一个真正的复本,而只是该数据的又一个引用。

当按引用比较时,要想比较成功,两个变量必须参照完全相同的实体。例如,两个不同的 Array 对象即使包含相同的元素也将比较为不相等。要想比较成功,其中一个变量必须为另一个的参考。要想检查两个数组是否包含了相同的元素,比较 toString() 方法的结果。

最后,字符串是按引用(即地址)复制和传递的,但是是按值来比较的。
请注意,假如有两个 String 对象(用 new String("something") 创建的),按引用比较它们,但是,如果其中一个或者两者都是字符串值的话,按值比较它们。

注意 鉴于 ASCII 和 ANSI 字符集的构造方法,按序列顺序大写字母位于小写字母的前面。例如 "Zoo" 小于 "aardvark"。如果想执行不区分大小写的匹配,可以对两个字符串调用 toUpperCase() 或 toLowerCase()。

传递参数给函数
按值传递一个参数给函数就是制作该参数的一个独立复本,即一个只存在于该函数内的复本。即使按引用传递对象和数组时,如果直接在函数中用新值覆盖原先的值,在函数外并不反映新值。只有在对象的属性或者数组的元素改变时,在函数外才可以看出。

例如(使用 IE 对象模式):

// 本代码段破坏(覆盖)其参数,所以
// 调用代码中反映不出变化。
function Clobber(param)
{
// 破坏参数;在调用代码中
// 看不到。
param = new Object();
param.message = "This will not work";
}

// 本段代码改变参数的属性,
// 在调用代码中可看到属性改变。
function Update(param)
{
// 改变对象的属性;
// 可从调用代码中看到改变。
param.message = "I was changed";
}

// 创建一个对象,并赋给一个属性。
var obj = new Object();
obj.message = "This is the original";

// 调用 Clobber,并输出 obj.message。注意,它没有发生变化。
Clobber(obj);
window.alert(obj.message); // 仍然显示 "This is the original"。

// 调用 Update,并输出 obj.message。注意,它已经被改变了。
Update(obj);
window.alert(obj.message); // 显示 "I was changed"。

检验数据
当按值进行检验时,是比较两个截然不同的项以查看它们是否相等。通常,该比较是逐字节进行的。当按引用进行检验时,是看这两项是否是指向同一个原始项的指针。如果是,则比较结果是相等;如果不是,即使它们每个字节都包含完全一样的值,比较结果也为不相等。

按引用复制和传递字符串能节约内存;但是由于在字符串被创建后不能进行更改,因此可以按值进行比较。这样可以检查两个字符串是否包含相同的内容,即使它们是完全独立产生的。

 


我的理解,在javaScript中,简单的说来,传值是通过建立实际值的拷贝来进行各种操作,而传址是在各种操作中,传递的是实际值的地址,实际值在操作过程中直接被改变的。在javaScript中,数字和布尔类型是由很小的

固定数目的字节组成,因此适用传值操作;而对象,包括数组和函数,他们的大小无法固定,可能会变得很大,如果用传值操作,可能会牵涉到对大量的内存低效率的复制和比较,效率低没有什么意义,因此适用传址操作,用代码实例说话:
传值:

结果显示:

value of n is 1
n的值并没有随m的值的变化而变化,说明m只是建立了n的数值拷贝,传值操作。

传址:

结果显示:
tomorrow is Thu Dec 11 2008 00:00:00 GMT+0800
today is Thu Dec 11 2008 00:00:00 GMT+0800
today 不等于 tomorrow
结果很明显,修改tomorrow的值以后,today的值也改变了;

同时建立了两个相同值date对象,他们却不相同;
=》传址操作
而javaScript中的字符串是一个特例,它是通过传址来复制和传递的,通过传值来进行比较的。
原因:首先,为什么说字符串是传址的呢?很明显,字符串的长度不定,它可以是任意长度,而且它不是对象,没有方法去修改字符串的内容;接下来,为什么说字 符串是传值的呢?在java、C和C++中,字符串不可以用“==”进行比较,而在javaScript中可以直接通过“==”进行值比较
分享到:
评论

相关推荐

    浅谈js中的引用和复制(传值和传址)

    同样,对于字符串,虽然其内容不可变,但在比较时被视为传值比较。 然而,对于引用类型,赋值实际上是复制了一个引用,即进行“传址”。例如,`var a = [1]; var b = a;`此时,`b`和`a`都指向同一个数组。如果修改`...

    JavaScript基础篇之变量作用域、传值、传址的简单介绍与实例

    在学习JavaScript基础时,变量作用域、传值与传址是核心概念,它们在编程过程中有着举足轻重的作用。本文将对这些概念进行简单介绍,并通过实例加深理解。 首先,关于变量作用域。在JavaScript中,变量的作用域决定...

    javascript的变量、传值、传址、参数之间关系

    JavaScript是一种动态类型的脚本语言,其变量、传值、传址和参数之间的关系是理解和使用JavaScript中的一个基础但关键点。接下来,我会详细解释这些概念。 首先,JavaScript中的变量可以存储两种类型的数据:基本...

    js代码-函数调用的传值和传址

    在JS中,参数传递有两种方式:传值(by value)和传址(by reference)。了解这两种方式对于编写高效、可维护的代码至关重要。 首先,我们来详细解释传值和传址的概念: 1. **传值(by value)**: 当一个基本...

    javascript中的变量是传值还是传址的?

    在这种情况下,变量间的赋值操作是传值,传递的是值的副本。 ```javascript var stringValue = "淡淡的"; var anotherStringValue = stringValue; stringValue = "I have changed"; ``` 在这个例子中,`...

    最新大厂前端面试题-面试指南JavaScript篇面试题.docx

    本文将对 JavaScript 基础知识点进行总结,涵盖数据类型、类型转换、作用域、变量提升、传值 VS 传址等知识点。 数据类型 JavaScript 中有 7 种基本数据类型:string、number、object、boolean、null、undefined ...

    JavaScript 函数参数是传值(byVal)还是传址(byRef) 分享

    实际上,JavaScript总是以传值(byVal)的方式传递参数,但这并不意味着对于所有类型的值都表现为传统的传值行为。理解这一点的关键在于理解JavaScript中的值类型(如number、string)和引用类型(如Object、Array)...

    Java初级教材 连载

    【Java初级教材 连载】章节内容主要涵盖了JavaScript的基础知识,包括数据类型、对象与基本类型之间的转换、数据操作、变量的传递方式、垃圾收集机制以及变量的作用域。以下是详细解释: 1. **对象与基本类型转换**...

    Javascript入门学习第二篇 js类型第1/2页

    在JavaScript中,基本数据类型如数字(Number)和布尔(Boolean)是通过传值的方式操作的,而对象类型如数组(Array)和函数(Function)则是通过传址的方式操作。 ### JavaScript中操作数据值的方式 JavaScript提供了三种...

    js-final-prep:技术面试的最后一分钟准备

    4. **函数**:了解函数的定义、参数传递(传值与传址)以及作用域(全局和局部)。另外,箭头函数的语法和其与传统函数的区别也是考察的重点。 5. **对象与原型**:JavaScript的对象是一种键值对的数据结构,而原型...

Global site tag (gtag.js) - Google Analytics