前言:

JavaScript 的变量与其他语言的变量有很大区别。JavaScript 变量松散类型的本质,决定了它只是在特定时间用于保存特定值的一个名字而已。由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变。尽管从某种角度看,这可能是一个既有趣又强大,同时又容易出问题的特性,但 JavaScript 变量实际的复杂程度还远不止如此

目录

基本类型和引用类型的值

ECMAScript 变量可能包含两种不同数据类型的值:基本类型值引用类型值。基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象。

在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型值。目前有 7 种基本数据类型:Undefined、Null、Boolean、Number 、 String、symbol和bigint。这 7 种基本数据类型是按值访问的,因为可以操作保存在变量中的实际的值。

引用类型的值是保存在内存中的对象。与其他语言不同,JavaScript 不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象。为此,引用类型的值是按引用访问的

(这种说法不严密,当复制保存着对象的某个变量时,操作的是对象的引用。但在为对象添加属性时,操作的是实际的对象。——图灵社区“壮壮的前端之路”注)。

复制变量值

在从一个变量向另一个变量复制基本类型值引用类型值时,也存在不同。如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上。来看一个例子:

var num1 = 5;
var num2 = num1;

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

var obj1 = new Object();
var obj2 = obj1;
obj1.name = "Nicholas";
alert(obj2.name); //"Nicholas"

传递参数

ECMAScript 中所有函数的参数都是按值传递的也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量的复制一样,而引用类型值的传递,则如同引用类型变量的复制一样。有不少开发人员在这一点上可能会感到困惑,因为访问变量有按值和按引用两种方式,而参数只能按值传递。

在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数,或者用ECMAScript 的概念来说,就是 arguments 对象中的一个元素)。在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部。

//例子1 基本数据类型作为参数

function addTen(num) {
num += 10;
return num;
}
var count = 20;
var result = addTen(count);
alert(count); //20,没有变化
alert(result); //30 //例子2 引用类型作为参数
function setName(obj) {
obj.name = "Nicholas";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"

可能有人错误地认为:在局部作用域中修改的对象会在全局作用域中反映出来,就说明参数是按引用传递的。为了证明对象是按值传递的,我们再看一看下面这个经过修改的例子:

//例子1 参数按值传递
function setName(obj) {
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"

这说明即使在函数内部修改了参数的值,但原始的引用仍然保持未变。实际上,当在函数内部重写 obj 时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。

检测类型

要检测一个变量是不是基本数据类型?第 3 章介绍的 typeof 操作符是最佳的工具。说得更具体一点,typeof 操作符是确定一个变量是字符串、数值、布尔值,还是 undefined 的最佳工具。如果变量的值是一个对象或 null,则 typeof 操作符会像下面例子中所示的那样返回"object":

var s = "Nicholas";
var b = true;
var i = 22;
var u;
var n = null;
var o = new Object();
alert(typeof s); //string
alert(typeof i); //number
alert(typeof b); //boolean
alert(typeof u); //undefined
alert(typeof n); //object
alert(typeof o); //object

通常,我们并不是想知道某个值是对象,而是想知道它是什么类型的对象(包含普通对象Object,数组对象Array,正则对象RegExp,日期对象Date,数学函数Math,函数对象Function)。为此,ECMAScript提供了instanceof 操作符,其语法如下所示:

result = variable instanceof constructor

alert(person instanceof Object); // 变量 person 是 Object 吗?
alert(colors instanceof Array); // 变量 colors 是 Array 吗?
alert(pattern instanceof RegExp); // 变量 pattern 是 RegExp 吗?

根据规定,所有引用类型的值都是 Object 的实例。因此,在检测一个引用类型值和 Object 构造函数时,instanceof 操作符始终会返回 true。当然,如果使用 instanceof 操作符检测基本类型的值,则该操作符始终会返回 false,因为基本类型不是对象。

参考书籍 JavaScript高级程序设计

重温JavaScript基础(一) 基本类型和引用类型的值

重温JavaScript基础(二) 执行环境以及作用域链

重温JavaScript基础(三) 执行环境以及作用域链

基本类型和引用类型的值 [重温JavaScript基础(一)]的更多相关文章

  1. 4.1 基本类型和引用类型的值【JavaScript高级程序设计第三版】

    ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象. 在将一个值赋给变量时,解析器必须确定这个值是基 ...

  2. 《JavaScript高级程序设计》读书笔记 ---基本类型和引用类型的值

    变量.作用域和内存问题 基本类型和引用类型的值ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值.基本类型值指的是简单的数据段,而引用类型值指那些可能由多个值构成的对象.在 ...

  3. JS基本类型和引用类型的值

    JS中可以把变量分成两部分,基本类型和引用类型. 基本类型比较简单,包括:Undefined.Null.Boolean.Number和String,基本类型值就是简单的数据段:引用类型值可能由多个值构 ...

  4. 【Java】基本类型和引用类型(值传递)

    [关键词] [问题] · 加深对基本类型和引用类型的理解: [效果图] [分析] 參见最后的[參考资料] [解决方式] [代码] public void test() throws Exception ...

  5. JavaScript 深入了解基本类型和引用类型的值

    转载:https://segmentfault.com/a/1190000006752076 一个变量可以存放两种类型的值,基本类型的值(primitive values)和引用类型的值(refere ...

  6. Javascript高级程序设计——基本类型和引用类型的值

    ECMAScript中的变量有两种不同的数据类型的值: 基本类型:基本类型的值是简单的数据段.包括:Undefined.Null.Number.Boolean.String五种 引用类型:引用类型的值 ...

  7. 《JS高程》基本类型和引用类型的值学习笔记

    ECMAScript 变量可能包含两种不同数据类型的值:基本类型值和引用类型值. 创建方式类似:创建一个变量并为其赋值. (1)基本类型值和引用类型值比较 基本类型值 引用类型值 简单的数据段 可能由 ...

  8. 【JavaScript】基本类型和引用类型的值、引用类型

    一.前言        接着上一篇继续记笔记 二.内容         动态的属性 var person = new Object(); person.name = "Nicholas&qu ...

  9. javascript变量中基本类型和引用类型的详解解读

    前言: Javascript语言中的变量和其他语言的变量有很大区别,javascript松散类型的本质,决定了它只是在特定时间时间保存特定值得名字而已.由于不存在定义某个变量必须保存何种数据类型值的规 ...

随机推荐

  1. hdu2222 (AC自动机模板)

    题:http://acm.hdu.edu.cn/showproblem.php?pid=2222 学习出:https://bestsort.cn/2019/04/28/402/ 主要是fail的建立. ...

  2. [原]PInvoke导致栈破坏

    原, 总结, 调试, 调试案例  项目中遇到一个诡异的问题,程序在升级到.net4.6.1后会崩溃,提示访问只读内存区.大概现象如下: debug版不崩溃,release版稳定崩溃. 只有x64位的程 ...

  3. Android开发学习3

    学习内容: 1.复选框CheckBox 2.ImageView & 使用第三方库加载网络图片 3.列表视图ListView 4.网格视图GridView 5.ScrollView & ...

  4. 2020 CCPC Wannafly Winter Camp Day2-K-破忒头的匿名信

    题目传送门 sol:先通过AC自动机构建字典,用$dp[i]$表示长串前$i$位的最小代价,若有一个单词$s$是长串的前$i$项的后缀,那么可以用$dp[i - len(s)] + val(s)$转移 ...

  5. nginx限制IP访问网站

    需求:网站只允许指定IP访问,其他访问一律拒绝server { listen 80; server_name a.com; index index.html index.htm index.php; ...

  6. Nginx的下载与安装

    .创建文件输入网页中需要复制的 cat >/etc/yum.repos.d/nginx.repo<<EOF [nginx-stable] name=nginx stable repo ...

  7. 四剑客(sed)

    一. sed sed简介: 用Linux环境中的编辑器程序来编辑文本文件.这些编辑器可以让你用简单命令或鼠标单击来轻松地处理文本文件中的文本.但有时候,你会发现需要自动处理文本文件,可你又不想动用全副 ...

  8. python-django框架-电商项目-购物车模块开发_20191125

    python-django框架-电商项目-购物车模块开发 商品详情页js代码: 在商品详情页,有加入购物车按钮, 点击加减号可以增加减少,手动输入也可以, 点击加入购物车,就要加过去, 先实现加减的操 ...

  9. sql 优化之8个尽量

    查询语句的优化是SQL效率优化的一个方式,可以通过优化sql语句来尽量使用已有的索引,避免全表扫描,从而提高查询效率.最近在对项目中的一些sql进行优化,总结整理了一些方法. 1.在表中建立索引,优先 ...

  10. 接受H0的坏处|试验误差|置信度由来|

    生物统计与实验设计 置信度(0.05 0.01)是通过实验次数估计值的分布得到的,它是整个分布的期望,这个值的确立需要具体情况具体分析. 肯定很难,因为否定一次很容易.虽然如果没有否定(eg:得到p= ...