Javascript与C#对变量的处理方式
先来看一下Javascript的情况(下面所说的基本类型和简单类型是一个意思):
Javascript中变量会存在两种情况,一种是基本类型的,一共有五种,有null、Bollean、undefined、number、还有string。基本类型是指简单的数据段,这些类型的值是直接存储在变量中的,也就是说,访问变量是是直接访问变量中的值,是按值访问的。另外一种是引用类型,引用类型的值保存在内存中(堆),如果要访问引用类型的值,就要通过这个指向该对象的引用类型的变量来进行访问。Javascript不允许直接操作对象的内存空间。值得注意的时Js中的string类型是一个值类型。不论是值类型还是引用类型,Js中的变量只是一个保存值的名字,这个名字可以用来保存任意类型的值。定义一个变量后,这个变量可以随时随地的保存其他任何类型的值。简单类型的变量和引用类型的变量的区别在于复制的机制不同。复制一个基本类型的变量时会将原有变量的值重新复制一份,也就是说复制之后这两个时完全独立的,对一个进行操作不会引起另一个的改变。而复制一个引用类型的变量时,也是将变量中的值重新复制一份出来,不同的是引用类型的变量中包含的值就是一个指针,指向内存中(堆)真正的对象。也就是说复制后两个变量是共享一个对象,其中任何一个进行操作后都会去改变这个对象:
var obj1 = new Object();
var obj2 = obj1;
obj1. name = "Nicholas";
alert( obj2. name); //"Nicholas"
传递参数方面JS都是按值进行传递的。
ECMAScript 中 所有 函数 的 参数 都 是按 值 传递 的。也就是说,把函数外部的值复制给函数内部的参数, 就和把值从一个变量复制到另一个变量一样。 基本类型值的传递如同基本类型变量的复制一样, 而引用类型值的传递, 则如同引用类型变量的复制一样。 有不少开发人员在这一点上可能会
感到困惑,因为访问变量有按值和按引用两种方式, 而参数只能按值传递。 泽卡斯(Zakas. Nicholas C.). JavaScript高级程序设计(第3版) (图灵程序设计丛书) (Kindle 位置 2623-2626). 人民邮电出版社. Kindle 版本.
在来看一下C#的情况:C#也包含两种数据类型,一种是简单数据类型,有byte、short、int、long、flaot、double、boolean、char等,这些简单数据类型都是简单数据类型,也叫做值类型,其值存储在变量本身,对这种类型的变量进行操作时会直接操作这个变量本身,与Js不同的是string是对象类型,值存储在堆上。另外一种就是对象类型,也叫做引用类型,对象是存储在堆上进行实例化后的一种叫法,当new一个对象类型时,会返回一个指向该对象的引用,这个引用(值)存储在一个栈上的变量中(有关实例化值类型变量后具体的存储位置,和值类型变量实例化的时机和地方有关。在C# in depth中有介绍。),也就是说,该变量的值保存的是一个引用,操作对象时都是通过这个引用来操作保存在堆上的对象。这个也就造成了C#中值类型和引用类型的根本区别在于复制的机制不同。在c#不论是值类型还是引用类型都可以进行按值传递和按引用传递,按值传递就是将变量的值进行一份拷贝,而按引用进行传递实际上是传递一个原有变量的“别名”,也就是说,按值传递的话操作的是另外一份数据,而按引用传递的话是操作的同一份数据,但是这个在值类型和引用类型中所引发的后果也是稍有不同的,值类型因为其值本身在变量中保存,如果按值进行传递的话那连同这个变量和值是一起被拷贝的,就是说在栈上另外开辟了一块空间来保存这个副本,那这样的话对原有的值是不会产生任何影响的。看下面的例子:
class Program
{
static void Main(string[] args)
{
int shit = 2;
Console.WriteLine("before:"+shit);//返回2
DoSome(shit);
Console.WriteLine("after:"+shit);//返回2
Console.WriteLine(DoSome(shit));//返回3
Console.ReadKey();
} public static int DoSome(int shit)
{
shit++;
return shit;
}
}
而如果按引用去传递一个值类型的变量,那么就是将原有变量起了一个别名后传递了出去,实际上“别名”和原有的变量共享了一份值。那么不论是对“别名”进行操作还是对原有变量进行操作都会改变值,看下面的例子:
class Program
{
static void Main(string[] args)
{
int shit = 2;
Console.WriteLine("before:"+shit);//返回2
DoSome(ref shit);
Console.WriteLine("after:"+shit);//返回3
Console.WriteLine(DoSome(ref shit));//返回4
Console.ReadKey();
} public static int DoSome(ref int shit)
{
shit++;
return shit;
}
}
上面说的都是C#中值类型的按值传递和按引用传递的区别。顺便说一下,C#中按引用传递分为ref和out,这两个关键字都是用来表示按引用进行传递,就是对实参的初始化的时机有所不同。一个是必须在使用前进行初始化(out),ref则没有这样的要求。
对于C#中引用类型的按值传递和按引用传递,又与值类型的按值传递和按引用传递的表现有所不同,引用类型的按值传递同理也是连变量带值都拷贝了一份,不同于值类型的是引用类型变量的值本身只是一个指向对象的引用,保存的是一个地址,所以引用类型的变量按值传递时也会有可能去改变堆上的变量,也有可能不会改变,比如将引用类型的变量按值传递出去之后马上对它进行一个new的操作,从而使它重新指向一个堆上的新地址。:)而对引用类型的变量进行按引用传递时同理也是其一个别名,这个别名和原来的对象都是共享一个值(指向堆上对象的引用)所以对这个别名进行的任何操作都会改变堆上的这个对象。
18:21:51
Javascript与C#对变量的处理方式的更多相关文章
- java基础58 JavaScript的几种格式和变量的声明方式(网页知识)
1.JavaScript的几种格式 1.1.JavaScript的特点 1.跨平台性 2.安全性.(javaScript代码不能直接访问电脑硬盘上的信息) 1.2.Java与javaScript ...
- Javascript中的循环变量声明,到底应该放在哪儿?
相信很多Javascript开发者都在声明循环变量时犹豫过var i到底应该放在哪里:放在不同的位置会对程序的运行产生怎样的影响?哪一种方式符合Javascript的语言规范?哪一种方式和ecma标准 ...
- JavaScript的作用域和变量对象
变量对象 先来说说什么是变量对象.变量对象中又存储了什么东西吧. JavaScript中的运行环境包含全局运行环境和函数运行环境这两种,每进入到一个运行环境都会创建一个变量对象,这个对象中记录了在当前 ...
- javascript基础语法备忘录-变量和数据类型
//javascript基础语法备忘录-变量和数据类型 // 定义变量使用var关键字 后面跟变量名,不要使用eval 和arguments为变量名 var message = "hi&qu ...
- smarty中三种变量的访问方式
在模板中smarty有三种变量,第一种,php分配的变量,第二种配置文件里的变量,第三种,PHP全局数组里的变量,配置文件里变量的访问方式可以是{#bgcolor#},"#"必须紧 ...
- JavaScript获取后台C#变量以及调用后台方法
http://www.educity.cn/develop/495493.html 有时需要在JavaScript中获取后台变量的值,来判断JavaScript的执行逻辑,或者需要调用C#后台方法获取 ...
- JavaScript神一样的变量系统
话说上一篇介绍了JavaScript故事版的身世之谜.看官你估计也明白JavaScript出生之时,就未曾托于重任.布兰登-艾奇估计也没料到今天的JavaScript变得如此重要.要不然,当年他也不会 ...
- Java中final变量的初始化方式
原文转自:http://blog.csdn.net/zhangjk1993/article/details/24196847 public class FinalTest1 { //--------- ...
- [转]javascript指定事件处理程序包括三种方式:
javascript指定事件处理程序包括三种方式: (1):DOM0级事件处理程序 如: 代码如下: var btn=document.getElementById("mybtn" ...
随机推荐
- nginx 拦截 swagger 登录
随着微服务的也来越多,每个服务都有单独的文档,那么问题来了,怎么把所有文档整合在一起呢 本方法采用服务器拦截的方式进行处理 首先需要在opt 的主目录中 /opt/ 创建一个新文件 htpasswd此 ...
- margin-left:-20px
对于负的margin值,设置其作用时要和position:absolute;一起使用
- iptables 从一台机到另一台机端口转发
启用网卡转发功能#echo 1 > /proc/sys/net/ipv4/ip_forward 举例:从192.168.0.132:21521(新端口)访问192.168.0.211:1521端 ...
- mysql执行顺序
SELECT语句执行顺序 SELECT语句中子句的执行顺序与SELECT语句中子句的输入顺序是不一样的,所以并不是从SELECT子句开始执行的,而是按照下面的顺序执行: 开始->FROM子句-& ...
- (1) 安卓导入mqtt包基本通信
参考资料:http://blog.csdn.net/qq_17250009/article/details/52774472 MQTT官网:http://mqtt.org/ MQTT介绍:http:/ ...
- CentOS7.4 ISCSI
试验机配置: cat /etc/centos-release CentOS Linux release 7.4.1708 (Core) uname -r 3.10.0-693.el7.x86_64 所 ...
- IDEA 编译 Jmeter 4.0 ( 二次开发_1 )
IDEA 编译 Jmeter 下载 http://jmeter.apache.org/download_jmeter.cgi 下载源码后解压『Jmeter』,我这边下载的是最新的『apache-jme ...
- Recurrent Neural Network[SRU]
0.背景 对于如机器翻译.语言模型.观点挖掘.问答系统等都依赖于RNN模型,而序列的前后依赖导致RNN并行化较为困难,所以其计算速度远没有CNN那么快.即使不管训练的耗时程度,部署时候只要模型稍微大点 ...
- There is no action xxxFun defined for api controller api/subitem
在使用abp的框架时,访问某个接口方法出现错误: There is no action xxxFun defined for api controller api/subitem 原因:肯定是访问的接 ...
- 【原创】JAVA8之妙用Optional解决NPE问题
引言 在文章的开头,先说下NPE问题,NPE问题就是,我们在开发中经常碰到的NullPointerException.假设我们有两个类,他们的UML类图如下图所示 在这种情况下,有如下代码 user. ...