“如何制作一个对象”;“生活”;在Javascript中,而不将其绑定到DOM

“如何制作一个对象”;“生活”;在Javascript中,而不将其绑定到DOM,javascript,dom,nodelist,Javascript,Dom,Nodelist,我昨天在IRC聊天中询问,是否有可能通过对它引用的对象的任何更改来更新元素,而不仅仅是保留声明时给出的值。比如说 Arr1 = [1,2,3] i1 = Arr1.length-1 last1 = Arr1[i1] Arr1.push(4) 在这个(任意)示例的末尾选中last1,表明它没有更新以反映新添加的值4,因此JS中的对象在默认情况下不是“活动的” 我是一个初学者,但我已经在实践中解决了这个问题,但有人告诉我事实就是如此。。。我想我的问题没有被理解 NodeList对象是“活动”的,

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

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

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

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


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

这里的一个重要区别是
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);

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

这里的一个重要区别是,
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);

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

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

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

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

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

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

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

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

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

我认为您误解了live的含义,因为即使
Arr1
是节点列表,last1仍将保持不变。在节点列表的上下文中生活意味着如果你更新DOM,节点列表也会更新。不,我知道,我对“生活”的含义不是很严格,我确实理解DOM,我只是想知道是否经常遇到此类问题,以及是否有其他解决方法,我认为您误解了live的含义,因为即使
Arr1
是节点列表,last1仍将保持不变。在节点列表的上下文中生活意味着如果你更新DOM,节点列表也会更新。不,我知道,我对“生活”的含义不是很严格,我确实理解DOM,我只是想知道这种问题是否经常遇到,以及是否有其他的解决方法。谢谢你更新了你的答案——这实际上更像我的想法!使用函数似乎有点尴尬,尤其是因为在循环中声明函数是一种不好的做法。事实上,它们本身就是对象(由函数构造函数生成),这向我建议应该有一种方法。为这个巨大的答案干杯!但是有一个问题-有没有一种方法可以引用这些属性。。。?像是
obj1.properties.length
还是什么<代码>obj1。长度为
未定义
a