这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
这篇文章主要介绍了 JavaScript 给 input 的 value 赋值引发的关于基本类型值和引用类型值问题的相关资料, 需要的朋友可以参考下
在自己做东西时,遇见了一个问题。就拿博客园的首页右边的搜索举例吧,用控制台操作。
现在我需要从另外一个地方将数据传给 input, 让其在一刷新的时候就显示数据。
这不难啊,于是我按照我的理解做了
代码如下:
此时,id 为 zzk_q 的值应该为 测试 ,即 input 框内应该显示 测试 。但结果。。
咦,为什么没有变呢,不对啊,又来来回回变着法子试一下,还是不行,当然代码基本还是那样子的。突然想起我以前遇见过这样子的问题,仔细回想当时解决的方法(看样子当时没理解透,只是找到方法就过去了),想起来了,我试一下, 代码如下:
看结果:
这次成了。第一次遇见这个问题时没有细想,成功了就跳过了。但这次我开始想为什么呢?为什么呢?怎么会这样啊,没办法理解啊。然后我自己在哪里来回折腾,但还是想不明白。同样是赋值这俩者有什么差别吗?差别在哪里啊?后来才知道是值类型和引用类型,当然是别人给我指出来的(……)。
然后我就去找这方面的东西看, 发现这东西我看过, 汗。
自 1997 年 Javascript 被标准化以来,它定义了六种基本类型。直到 ES6,JS 程序中任何一个值都属于以下几种类型之一。
•Undefined •Null •Boolean •Number •String •Object
不过,ES6 又加了一个基本类型:Symbol 类型。这个没多大了解,不作讨论,等以后熟悉再说吧,又要学。
在 JavaScript 的变量中,有俩种类型的值:基本类型和引用类型的值。基本类型值(也有人称为值类型)是简单地数据段,它是按值访问的,并对其中的值进行操作。而引用类型值值那些有可能有多个值构成的对象。赋值的时候,解释器必须确定值是基本类型还是引用类型。
基本数据类型有:Undefined、Null、Boolean、Number、String。引用类型是保存在内存中的对象,即 Object,对象是方法和属性结合。
1. 类型值的动态属性
这是引用类型:
- var person = new Object();
- person.name = "foo";
- console.log(person.name); //foo
- delete person.name;
- console.log(person.name) : //undefined
这个例子中,我们先创建了一个空对象,然后将其保存在 person 变量中,然后给对象添加了一个属性 name,而且给这个属性赋值了一个字符串 "foo",然后输出,可以看到输出了字符串 foo, 然后我们将这个属性删除,输出 undefined。这些说明,我们可以动态的给对象添加属性和方法,如果不销毁对象或者删除属性,将会一直存在。
这是基本类型:
- var name = "foo";
- name.age = 22;
- console.log(name.age); //undefined
在这个中,我们将一个字符串 "foo", 保存在一个 name 变量中,然后也给它添加了一个属性 age,并赋值 22,然后输出,像我以前想的那么该输出 22,但实际情况是 undefined。
这个是否可以理解为基本类型的值是不可变的, 而引用类型是可以动态改变的。
2. 复制变量值
和上面说的一样,基本类型是按值访问的。而引用类型呢,在 JavaScript 和其它语言不同,允许直接访问内存中的位置,也就是说我们不可以直接操作对象的内存空间,那怎么办呢?在操作对象时,实际上是对操作对象的引用,引用类型的值是按引用对象访问的。引用类型的存储需要内存的栈内存和堆内存共同完成,栈内存保存变量标识符和指向堆内存中该对象的指针,也可以说是该对象在堆内存的地址。
先看例子:
- var num1 = 5;
- var num2 = num1; //5
- num1 += 1; //6
- num2; //5
从一个变量向另一个变量复制基本类型的值,我们会在变量对象上重新创建一个新值,然后把该值复制到新变量分配的位置上。这俩个值是完全对立的,对俩个变量进行其他操作是互不影响的。它们应该是保存在栈内存中,如下图所示:
看一下引用类型:
- var obj1 = new Object();
- var obj2 = obj1;
- obj1.name = "foo";
- console.log(obj2.name); //foo
- obj2.age = 22;
- console.log(obj1.age); //22
当从一个变量想另一个变量复制引用类型的的值时,也会将该值复制一份放到新的空间中。但是就跟上面说的一样,引用类型的存储要栈内存和堆内存一起完成,这个值实际上是一个指针,而这个指针指向存储在堆中的一个对象。复制操作结束后,俩个变量实际上是同一个指针,也就是引用同一个对象。所以,改变其中的一个变量,另一个变量也会随之改变。如下图:
参看 JavaScript 高级程序设计。
这样一梳理,就对一开始的问题有些明白了,开头那个错误,一开始,取到 input 的 value(此时为空),复制给 title,然后以改变 title 期望改变 input 的 value。但 input 的 value(可以看成一个变量)就是一个基本类型,复制后,它俩完全独立了,互不影响。再说成功的,将 value 拿出来,先将 input(对象)复制给 title,然后给 title 添加 value 属性,并赋值,此时俩个指向同一个对象,改变一个,也会影响另外一个。恩,就这样子。
虽然很多知识从书上或其他地方看了一遍或多遍,但是等你真正遇到时感觉好奇怪。怎么会这样,然后自己去找答案。等找到或是别人指出后,才发现这个以前看见过,有些甚至自己解决过(不能说解决,只能说没有深究,没有彻底弄懂)。还有一些大学的基础都忘的七七八八了(本来就学的不好)。连栈内存和堆内存都去搜了一下。恩,既然决定走这条路了,就好好学习吧。
最后:
- Good good coding,
- day day up !
PS:(集合和引用类型、基本数据类型赋值不一样)一个简单的 java 问题 先后的赋值问题
- <span style="white-space:pre">
- </span>
- List
- <person>
- list = new ArrayList
- <person>
- ();
- <span style="white-space:pre">
- </span>
- person pp = new person();
- <span style="white-space:pre">
- </span>
- list.add(pp);
- <span style="white-space:pre">
- </span>
- pp.setIvalue(12);
- <span style="white-space:pre">
- </span>
- pp.setIvalue(20);
- <span style="white-space:pre">
- </span>
- pp = null;;
- <span style="white-space:pre">
- </span>
- int b = 0;
- <span style="white-space:pre">
- </span>
- int a = b;
- <span style="white-space:pre">
- </span>
- b = 8;
- <span style="white-space:pre">
- </span>
- System.out.println(a);
- <span style="white-space:pre">
- </span>
- for (person ppp : list) {
- <span style="white-space:pre">
- </span>
- ppp.getIvalue();
- <span style="white-space:pre">
- </span>
- }
- <span style="white-space:pre">
- </span>
list 里面的对象加进去就改不了,但是可以修改对象里面的属性值。
简单 string 里面的值就改变不了
结果:
11 8888
切记:最好还是按正常来写,避免混淆
来源: http://www.phperz.com/article/17/0412/268268.html