javascript 值传递与作用域

ECMAScript的变量是松散类型的,在将一个值赋给变量时,解析器必须确定这个值是基本类型还是引用类型。基本类型是按值访问的,因为可以操作保存在变量中的实际的值。
引用类型的值是保存在堆内存中的对象,JavaScript 不容许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是
操作实际的对象。因此 JavaScript 引用类型是按引用访问的。

对于引用类型我们可以为他添加属性和方法,但是我们不能给基本类型的值添加属性,虽然这样做不会导致任何的错误。如下所示:
var num = 1;
num.age = 12; //这里隐式调用了Number()将其转为Number对象,然后为其赋值,所以这里不会报错。执行完之后解除了该对象。
alert(num.age); //undefined

@复制变量
除了保存的方式不同之外,在一个变量向另一个变量复制基本类型和引用类型时,也存在不同。如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值
复制到为新变量分配的位置上。如下所示:

var num = 12;
var age = num;
age = 24;
alert(num); //12
alert(age); //24

上面的例子中num变量保存的是12 ,然后将num 复制给新变量 age,该值是num的一个副本。 然后修改了age 的值,最后打印这2个值,修改age 并没有改变num的值。

当从一个变量想另一个变量复制引用类型的值时,同样也会将存储在变量对象中的值复制一份放到为新变量分配的内存空间中。不同的是,这个值的副本实际上是一个指针,而这个指针
指向存储在堆内存中的一个对象,复制操作结束后,两个变量实际上将引用同一个对象。因此改变其中一个变量就会影响到另一个变量。 如下所示:

var po = {
age : 24,
name : "tony"
}

var ob = po;
ob.name = "miracle";
alert(po.name); //miracle
alert(ob.name); //miracle

如同上述代码所示,修改了复制后的变量ob的name 属性会影响 原来的po对象的name属性,因为这两个变量引用的是同一个对象,而他们的值都是指向该对象的指针。综上所述:
*引用类型复制,其实是复制了指针。

@参数传递
ECMAScript 中所有的函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制给另一个变量一样。基本类型值的传递如同基本类型
变量的复制一样,而引用类型值的传递,则如同引用类型的变量复制一样。在向参数传递基本类型值的时候,被传递的值会被复制给一个局部变量。在向参数传递引用类型时,会吧这个值在内存
中的地址复制给一个局部变量,因此这个局部变量的变化会反映到函数的外部。如下所示:

function basicFun(num){
num += 12;
return num;
}

var sum = 12;
var age = basicFun(sum);
alert(sum); //12
alert(age); //24

如上列代码所示,先定义了一个sum 其值为12, 然后调用basicFun()将sum复制给参数num,然后在basicFun()函数中参数 num 进行了+12操作,但这个操作不会影响
函数的外部变量sum。参数num与变量sum互不相识,他们只是具有相同值而已。使用基本类型比较简单,如果是使用引用类型就可能有些复杂了。请看下列代码。

function quoteFn(obj){
obj.name = "tony";
obj.age = 24;
obj = new Object();
obj.sex = "Men";
}

var person = {
name : "miracle",
age : 12
}

quoteFn(person);
alert(person.name); //tony
alert(person.age); //24
alert(person.sex); //undefined;

上列代码中创建了一个person对象,该对象的name 属性值为 "miracle",age 属性值为12。然后,这个变量被传递到quoteFn()中复制给参数obj,
在这个函数内部参数obj和变量person引用的是同一个对象。也就是说,即使这个变量是按值传递的,obj也会按引用来访问同一个对象,如是obj修改了name和
age属性的值之后,外部的person 也将有相同的反应。因为引用类型复制的是一个指向了对象的指针。而在quoteFn()函数中的第3行代码为参数obj重新创建
了一个对象,并为其添加了属性sex。如果person是按引用传递的,那么person就会制动修改为指向新对象。但是接下来访问新属性sex时,显示的是undefined;
这说明即使在函数的内部修改了参数的值,但原始的引用任然保持未变。实际上,在函数中重写obj时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行
完毕之后被立即销毁。

@检测类型
要检测一个变量是不是基本类型使用 typeof 操作符,而检测对象使用 instanceof 操作符, typeof 操作符返回该操作类型的字符串表示,
instanceof 操作符返回布尔值,如下所示;

alert(typeof true); //boolean
alert([] instanceof Array); //true

@执行环境和作用域
JavaScript 中没有块级作用域,他有全局作用域和函数作用域(局部作用域),全局执行环境是最外围的执行环境。根据ECMAScript实现所在的宿主环境不同,表示执行环境的对象也不一样。
在WEB浏览器中,全局执行环境被认为是window对象,因此所有的全局变量和函数都是window对象的属性和方法。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和
函数定义也随之销毁(全局执行环境知道应用退出--列如关闭网页或者浏览器)。
关于作用域链就是内部作用域可以访问外部作用域。

时间: 2024-08-12 10:22:37

javascript 值传递与作用域的相关文章

JavaScript值传递和引用传递

1?数据类型:boolean,null,undefined,String,Number,指向包含的数据,进行“值传递”: 2.非数据类型:Array,Function,Object,指向了一个内存地址,该地址存放了具体的数据,进行“引用传递”: 3.==和===只会判断引用的地址是否相同,而不会判断对象具体里属性以及值是否相同.因此,如果两个变量指向相同的对象,则返回true.如果想判断两个不同的对象是否真的相同,一个简单的方法就是将它们转换为字符串然后判断.另一个方法就是递归地判断每一个属性的

6 JavaScript函数&内置构造&函数提升&函数对象&箭头函数&函数参数&参数的值传递与对象传递

JavaScript函数:使用关键字function定义,也可以使用内置的JavaScript函数构造器定义 匿名函数: 函数表达式可以存储在变量中,并且该变量也可以作为函数使用. 实际上是匿名函数. <body> <p>函数存储在变量后,变量可作为函数使用:</p> <p id="demo"></p> <script> var x = function(a,b){return a+b; }; document.g

JavaScript的值传递和引用传递

本文和大家分享的主要是javascript中值传递和引用传递相关内容,一起来看看吧,希望对大家学习javascript有所帮助. JavaScript有5种基本的数据类型,分别是:布尔.null.undefined.String和Number.这些基本类型在赋值的时候是通过值传递的方式.值得注意的是还有另外三种类型: Array.Function和Object,它们通过引用来传递.从底层技术上看,它们三都是对象. 基本数据类型 如果一个基本的数据类型绑定到某个变量,我们可以认为该变量包含这个基本

JavaScript强化教程——对象的值传递和引用传递

本文为 H5EDU 机构官方 HTML5培训 教程,主要介绍:JavaScript强化教程--对象的值传递和引用传递 function SetName(obj){  obj.name="Tom";//执行之前,此时的obj和Person的name属性均为undefined  obj1=new Object();  obj1=obj;//声明一个全局对象,那么obj.obj1和Person此时应该是同一个对象  }//SetName函数执行完之后,obj对象销毁,其余对象仍然存在  Pe

Javascript 之《函数传参到底是值传递还是引用传递》

前言 这个问题其实困惑了我好久,但是在实际使用中总是得过且过,不想去深究.由于这种态度,在学习 Javascript 过程中,水平一直都是出于半桶水状态,很多概念和原理似懂非懂,模糊不清. 所以,写了一系列的<Javascript 之 ...>就是为了端正态度,认真地研究一下 Javascript 的特性和原理,夯实基础. 今天,这一篇探究的是函数传参的问题:函数传参到底是传值还是传的引用? 1.如果是引用传递 var name = 'JS'; function changeName(name

javascript中值传递与值引用的研究

今天重新看了一下<javascript高级程序设计>,其中讲到了javascript中的值传递和值引用,所以就自己研读了一下,但是刚开始没有明白函数中的参数只有值传递,有的场景好像参数是以引用的方式传递的,但是实际上却不是,那到底是怎么回事,或者是函数中的传值是值传递还是值引用呢,下面来对书上给出的例子做一个图解,这样能够更好的解释这个问题.有顿悟的感觉.javascript中貌似共有8种数据类型,包括了字符串类型,数值类型,布尔类型,undefined类型,null类型,对象,数组,函数:1

JavaScript 函数参数传递到底是值传递还是引用传递

tips:这篇文章是听了四脚猫的js课程后查的,深入的理解可以参看两篇博客: JavaScript数据类型--值类型和引用类型 JavaScript数据操作--原始值和引用值的操作本质 在传统的观念里,都认为JavaScript函数传递的是引用传递(也称之为指针传递),也有人认为是值传递和引用传递都具备.那么JS的参数传递到底是怎么回事呢?事实上以下的演示也完全可以用于Java 首先来一个比较简单的,基本类型的传递: function add(num){ num+=10; return num;

JavaScript进阶(三) 值传递和引用传递

从C语言开始 有时候讲一些细节或是底层的东西,我喜欢用C语言来讲,因为用C更方便来描述内存里面的东西.先举一个例子,swap函数,相信有一些编程经验的人都见识过,声明如下,函数体我就不写了,各位脑补一下. void swap1(int a, int b); void swap2(int* a, int* b) 这里swap1是不能交换两个数的值的,swap2可以.那为什么呢?有教材会说,第一个是值传递,第二个是引用传递,传递的是指针,所以第二个可以.好吧,这个解释和没说一样,那下面我就来解释一下

JavaScript中函数参数的值传递和引用传递

结论:对于数字.字符串等是将它们的值传递给了函数参数,函数参数的改变不会影响函数外部的变量. 对于数组和对象等是将对象(数组)的变量的值传递给了函数参数,这个变量保存的指向对象(数组)的地址.当函数改变这个地址指向的对象(数组)的内容时,同时也改变了函数外部变量指向的对象(数组)的内容:当函数改变的是变量的地址时,实际就与函数外部的变量失去了联系,变成了完全不同的对象了,不会对函数外部对象造成改变. 很多人认为 JS 中参数有两种传递方式:数字.字符串等按值传递:数组.对象等按地址(引用)传递.