代码之家  ›  专栏  ›  技术社区  ›  Louis Maddox

如何在Javascript中使对象“活”起来而不将其绑定到DOM

  •  1
  • Louis Maddox  · 技术社区  · 11 年前

    我昨天在IRC聊天中问过,是否可以通过对其引用的对象的任何更改来更新元素,而不仅仅是保留声明时给出的值。例如

    Arr1 = [1,2,3]
    i1 = Arr1.length-1
    last1 = Arr1[i1]
    
    Arr1.push(4)
    

    检查 last1 在这个(任意)示例的末尾,它没有更新以反映新添加的值4,因此JS中的对象在默认情况下不是“活动”的。

    我是一个初学者,但我已经在实践中解决了这个问题,但有人告诉我事实上就是这样。。。我想我的问题没有被理解。

    NodeList 然而,对象是“活的”,我想知道JS中是否有其他类型的对象这样做,因为这显然可以节省更新它们所花费的代码行。

    2 回复  |  直到 11 年前
        1
  •  3
  •   JLRishe    11 年前

    这里的一个重要区别是 i1 此处不“引用”任何内容。它只是存储表达式的数字结果 Arr1.length-1 当该行执行时。同样地 last1 可以引用,也可以不引用 Arr1 当执行第3行时,但它没有引用 第1项 它本身或它的任何东西。

    与其他一些编程语言一样,分配给对象的变量 引用,因此您可以执行以下操作:

    var obj1 = { prop1: "hello", prop2: "goodbye" };
    var obj2 = obj1;
    obj2.prop1 = "buongiorno";
    console.log(obj1.prop1);  // result is "buongiorno"
    

    但这似乎不是你所描述的那样。

    听起来你所描述的是某种反应式编程。JavaScript并不像你想象的那样工作,但你可以使用闭包来实现这一点:

    var Arr1 = [1,2,3];
    var i1 = function() { return Arr1.length - 1; };
    var last1 = function() { return Arr1[i1()]; };
    
    console.log(i1());    // result is 2
    console.log(last1()); // result is 3
    
    Arr1.push(4);
    
    console.log(i1());    // result is 3
    console.log(last1()); // result is 4
    

    注意,这里 () 调用这些函数并获取其当前值需要在末尾的括号。

    你可以做的一件更棘手的事情是:

    function capture(fcn) { 
        return { valueOf: fcn, toString: function() { return fcn().toString(); } };
    }
    
    var Arr1 = [1,2,3]
    var i1 = capture(function() { return Arr1.length - 1; });
    var last1 = capture(function() { return Arr1[i1]; });
    
    console.log(last1 * 5); // result is 15
    
    Arr1.push(4);
    
    console.log(last1 * 5); // result is 20
    

    然而,请注意,第二种技术有其局限性。您必须将值强制为您期望的类型或调用它们的类型 .valueOf() 方法,以便它们产生实际值。如果您刚刚使用:

    console.log(last1);
    

    你不会得到任何友好的结果。

        2
  •  1
  •   Christian Landgren    11 年前

    我将您的问题解释为,为什么当您更改原始值时,某些变量是副本,而其他变量不是副本。

    这是因为某些类型的变量是引用类型,而其他类型的变量则是值类型。数字、日期和字符串是值类型,每当您将它们分配给变量时都会被复制。对象、数组(也是一个对象)是引用类型,不会复制,只是引用。

    此示例使用值类型,不会复制对第一个变量的任何更改:

    var foo = 1;
    var bar = foo; // this is copying the value from the foo variable to bar
    foo = 2;
    console.log(bar); // 1
    

    与同一事物相比,但与对象的引用相比:

    var foo = {prop:1};
    var bar = foo; // this is creating a reference to the foo object
    foo.prop = 2;
    console.log(bar.prop); // 2