JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题


Posted in Javascript onDecember 07, 2015

 在自己做东西时,遇见了一个问题。就拿博客园的首页右边的搜索举例吧,用控制台操作。

 

JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题

JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题

现在我需要从另外一个地方将数据传给input,让其在一刷新的时候就显示数据。

这不难啊,于是我按照我的理解做了

代码如下:

JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题

此时,id为zzk_q的值应该为  测试  ,即input框内应该显示 测试 。但结果。。

JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题

咦,为什么没有变呢,不对啊,又来来回回变着法子试一下,还是不行,当然代码基本还是那样子的。突然想起我以前遇见过这样子的问题,仔细回想当时解决的方法(看样子当时没理解透,只是找到方法就过去了),想起来了,我试一下,代码如下:

JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题

看结果:

 JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题

这次成了。第一次遇见这个问题时没有细想,成功了就跳过了。但这次我开始想为什么呢?为什么呢?怎么会这样啊,没办法理解啊。然后我自己在哪里来回折腾,但还是想不明白。同样是赋值这俩者有什么差别吗?差别在哪里啊?后来才知道是值类型和引用类型,当然是别人给我指出来的(……)。

然后我就去找这方面的东西看,发现这东西我看过,汗。

  自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

 从一个变量向另一个变量复制基本类型的值,我们会在变量对象上重新创建一个新值,然后把该值复制到新变量分配的位置上。这俩个值是完全对立的,对俩个变量进行其他操作是互不影响的。它们应该是保存在栈内存中,如下图所示:

JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题 

看一下引用类型: 

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赋值引发的关于基本类型值和引用类型值问题

参看 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  

切记:最好还是按正常来写,避免混淆

Javascript 相关文章推荐
Javascript匿名函数的一种应用 代码封装
Jun 27 Javascript
div当滚动到页面顶部的时候固定在顶部实例代码
May 27 Javascript
jQuery中prev()方法用法实例
Jan 08 Javascript
js控制文本框只输入数字和小数点的方法
Mar 10 Javascript
vue实现表格增删改查效果的实例代码
Jul 18 Javascript
浅谈vue首屏加载优化
Jun 28 Javascript
vue  directive定义全局和局部指令及指令简写
Nov 20 Javascript
解决IOS端微信H5页面软键盘弹起后页面下方留白的问题
Jun 05 Javascript
layui将table转化表单显示的方法(即table.render转为表单展示)
Sep 24 Javascript
js实现3D照片墙效果
Oct 28 Javascript
vue 实现锚点功能操作
Aug 10 Javascript
深入了解Vue3模板编译原理
Nov 19 Vue.js
小巧强大的jquery layer弹窗弹层插件
Dec 06 #Javascript
使用jQuery+EasyUI实现CheckBoxTree的级联选中特效
Dec 06 #Javascript
javascript字符串函数汇总
Dec 06 #Javascript
win7下安装配置node.js+express开发环境
Dec 06 #Javascript
分享使用AngularJS创建应用的5个框架
Dec 05 #Javascript
如何利用AngularJS打造一款简单Web应用
Dec 05 #Javascript
使用CDN和AJAX加速WordPress中jQuery的加载
Dec 05 #Javascript
You might like
写一个用户在线显示的程序
2006/10/09 PHP
一个颜色轮换的简单例子
2006/10/09 PHP
php 全局变量范围分析
2009/08/07 PHP
PHP开发中四种查询返回结果分析
2011/01/02 PHP
跟着Jquery API学Jquery之一 选择器
2010/04/07 Javascript
用js来解决ajax读取页面乱码
2010/11/28 Javascript
Flex通过JS获取客户端IP和计算机名的实例代码
2013/11/21 Javascript
使用jQuery UI库开发Web界面的简单入门指引
2016/04/22 Javascript
Angularjs之filter过滤器(推荐)
2016/11/27 Javascript
javascript滚轮事件基础实例讲解(37)
2017/02/14 Javascript
angularjs实现搜索的关键字在正文中高亮出来
2017/06/13 Javascript
Angularjs在360兼容模式下取数据缓存问题的解决办法
2017/06/22 Javascript
JavaScript闭包与作用域链实例分析
2019/01/21 Javascript
JS中的算法与数据结构之字典(Dictionary)实例详解
2019/08/20 Javascript
微信小程序批量监听输入框对按钮样式进行控制的实现代码
2019/10/12 Javascript
解决vue字符串换行问题(绝对管用)
2020/08/06 Javascript
[00:29]2019完美世界全国高校联赛(秋季赛)总决赛海口落幕
2019/12/10 DOTA
Python实例之wxpython中Frame使用方法
2014/06/09 Python
python计算对角线有理函数插值的方法
2015/05/07 Python
python实现的系统实用log类实例
2015/06/30 Python
深入浅析Python字符编码
2015/11/12 Python
PyTorch快速搭建神经网络及其保存提取方法详解
2018/04/28 Python
详解基于python的多张不同宽高图片拼接成大图
2019/09/26 Python
Python中Selenium库使用教程详解
2020/07/23 Python
前端canvas水印快速制作(附完整代码)
2019/09/19 HTML / CSS
html5绘制时钟动画
2014/12/15 HTML / CSS
法国和欧洲海边和滑雪度假:Pierre & Vacances
2017/01/04 全球购物
软件测试工程师笔试题带答案
2015/03/27 面试题
质检员的岗位职责
2013/11/15 职场文书
员工评语大全
2014/01/19 职场文书
经典广告词大全
2014/03/14 职场文书
离婚协议书范本样本
2014/08/19 职场文书
投资意向协议书
2015/01/29 职场文书
应用最多的公文《通知》如何写?
2019/04/02 职场文书
公文格式,规则明细(新手收藏)
2019/07/23 职场文书
win10截图快捷键win+shift+s没有反应无法截图怎么解决?
2022/08/14 数码科技