zoukankan      html  css  js  c++  java
  • javascript不可变的原始值和可变的对象引用

    来自:《JavaScript权威指南(原书第6版)》第3章类型、值和变量,

    (以前也有一篇文章非常好:http://www.cnblogs.com/youxin/archive/2012/08/23/2653292.html javascript数据类型)

    JavaScript中的原始值(undefined、null、布尔值、数字和字符串)与对象(包括数组和函数)有着根本区别。原始值是不可更改的:任何方法都无法更改(或“突变”)一个原始值。对数字和布尔值来说显然如此——改变数字的值本身就说不通,而对字符串来说就不那么明显了,因为字符串看起来像由字符组成的数组,我们期望可以通过指定索引来修改字符串中的字符。实际上,JavaScript是禁止这样做的。字符串中所有的方法看上去返回了一个修改后的字符串,实际上返回的是一个新的字符串值。例如:

    1. var s = "hello";    // 定义一个由小写字母组成的文本  
    2. s.toUpperCase();    // 返回"HELLO",但并没有改变s的值  
    3. s               // => "hello": 原始字符串的值并未改变 

    原始值的比较是值的比较:只有在它们的值相等时它们才相等。这对数字、布尔值、null和undefined来说听起来有点儿难懂,并没有其他办法来比较它们。同样,对于字符串来说则并不明显:如果比较两个单独的字符串,当且仅当它们的长度相等且每个索引的字符都相等时,JavaScript才认为它们相等。

    对象和原始值不同,首先,它们是可变的——它们的值是可修改的:

    1. var o = { x:1 };    // 定义一个对象  
    2. o.x = 2;        // 通过修改对象属性值来更改对象  
    3. o.y = 3;        // 再次更改这个对象,给它增加一个新属性  
    4.  
    5. var a = [1,2,3]     // 数组也是可修改的  
    6. a[0] = 0;       // 更改数组的一个元素  
    7. a[3] = 4;       // 给数组增加一个新元素 

    对象的比较并非值的比较:即使两个对象包含同样的属性及相同的值,它们也是不相等的。各个索引元素完全相等的两个数组也不相等。

    1. var o = {x:1}, p = {x:1};   // 具有相同属性的两个对象  
    2. o === p             // => false: 两个单独的对象永不相等  
    3. var a = [], b = [];         // 两个单独的空数组  
    4. a === b                 // => false: 两个单独的数组永不相等 

    我们通常将对象称为引用类型(reference type),以此来和JavaScript的基本类型区分开来。依照术语的叫法,对象值都是引用(reference),对象的比较均是引用的比较:当且仅当它们引用同一个基对象时,它们才相等。

    1. var a = [];     // 定义一个引用空数组的变量a  
    2. var b = a;  // 变量b引用同一个数组  
    3. b[0] = 1;   // 通过变量b来修改引用的数组  
    4. a[0]        // => 1: 变量a也会修改  
    5. a === b         // => true:a和b引用同一个数组,因此它们相等 

    就像你刚看到的如上代码,将对象(或数组)赋值给一个变量,仅仅是赋值的引用值:对象本身并没有复制一次。如果你想得到一个对象或数组的副本,则必须显式复制对象的每个属性或数组的每个元素。下面这个例子则是通过循环来完成数组复制(见5.5.3节):

    1. var a = ['a','b','c'];      // 待复制的数组  
    2. var b = [];                 // 复制到的目标空数组  
    3. for(var i = 0; i < a.length; i++) {     // 遍历a[]中的每个元素  
    4.    b[i] = a[i];             // 将元素值复制到b中  

    同样的,如果我们想比较两个单独的对象或者数组,则必须比较它们的属性或元素。下面这段代码定义了一个比较两个数组的函数:

    1. function equalArrays(a,b) {  
    2.     if (a.length != b.length) return false;     // 两个长度不同的数组不相等  
    3.     for(var i = 0; i < a.length; i++)       // 循环遍历所有元素  
    4.         if (a[i] !== b[i]) return false;    // 如果有任意元素不等,则数组不相等  
    5.     return true;                // 否则它们相等  
  • 相关阅读:
    ◆ C++中通过溢出覆盖虚函数指针列表执行代码
    关于在OnTimer中连续弹出对话框的讨论
    SetTimer
    Windows内核对象
    日志收缩
    暴力求值
    低级问题
    函数限制
    字符串找字段和表
    android错误提示说明汇总
  • 原文地址:https://www.cnblogs.com/youxin/p/3060530.html
Copyright © 2011-2022 走看看