如何制作一个物品" live"在Javascript中没有将它绑定到DOM

时间:2014-03-22 14:12:05

标签: javascript dom nodelist

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

Arr1 = [1,2,3]
i1 = Arr1.length-1
last1 = Arr1[i1]

Arr1.push(4)

在此(任意)示例的末尾检查last1表示它没有更新以反映新添加的值4,因此JS中的对象不是" t"直播"默认情况下。

我是初学者,但我已经从练习中解决了这个问题,但有人告诉我实际情况就是这样......我想我的问题并没有被理解。

NodeList个对象是"直播"但是,我想知道JS中是否有其他类型的对象这样做,因为它显然会节省用于更新它们的代码行。

2 个答案:

答案 0 :(得分:3)

这里的一个重要区别是i1没有"引用"这里有什么。它只是在执行该行时存储表达式Arr1.length-1的数值结果。同样地,last1可能会或可能不会引用第3行执行时Arr1的第三个元素的值,但它不保留对Arr1本身或其任何内容的引用。

与其他一些编程语言一样,分配给对象的变量是引用,因此您可以这样做:

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);

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

答案 1 :(得分:1)

我将您的问题解释为为什么在更改原始值时更新某些变量副本而其他变量未更新。

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

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

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