作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我现在正在做 EloquentJS 书中的练习。更准确地说,第四章是“ list ”练习。该练习包括从数组创建列表以及从数组解构列表。
我尝试了一些对我来说看起来很逻辑的东西,但我得到了我不明白的返回。我得到一个圆形标签/标记。
这是我的第一次尝试和第二次尝试:
function arrayToListTry1 (array) {
/**My solution try 1
My observations:
I was building it inverted (last elem in first place
I don't understand why my version gets a circular result and the book solution doesn't
*/
let list = {
value: "",
rest: {}
};
for (let i = 0; i < array.length; i++) {
list.rest = list;
list.value = array[i];
}
return list;
}
/**result:
node eloquentJS_chapter4_ex_arrayToList.js
{ rest: [Circular], value: 'hello' }
*/
function arrayToListTry2 (array) {
let list = {};
for (let i = array.length - 1; i >= 0; i--) {
list.rest = list;
list.value = array[i];
}
return list;
}
//same result
练习解决方案显示了我检查它的另一种方式,但不清楚我的解决方案有什么问题。我还在 stackoverflow 上查看了其他人对这个练习的看法,但没有找到我理解的解释。
以下是实际的练习解决方案:
function arrayToList(array) {
let list = null;
for (let i = array.length - 1; i >= 0; i--) {
list = {value: array[i], rest: list};
}
return list;
}
/**
result:
node eloquentJS_chapter4_ex_arrayToList.js
{ value: 'hello',
rest: { value: 'world', rest: { value: '!!!', rest: null } } }
*/
<小时/>
编辑:这是我的最终结果,我将跳过整个文件内容。谢谢大家。
let listValue = {
value: "hello",
rest: {
value: "world",
rest: {
value: "!!!",
rest: {}
}
}
};
const arrayValue = ["hello", "world", "!!!"];
function arrayToList (array){
/**Actual solution from book:
*/
// let list = null;
// for (let i = array.length - 1; i >= 0; i--) {
// list = {value: array[i], rest: list};
// }
// return list;
/**My solution try 1
My observations:
I was building it inverted (last elem in first place
I dont understand why my version gets a circular result and the book solution doesnt
*/
// let list = {
// // value: "",
// // rest: {
// //
// // }
// };
//
// for (let i = 0; i < array.length; i++) {
// list.rest = list;
// list.value = array[i];
// // console.log(list);
// // console.log(list.rest);
// }
// //console.log(list.rest);
// // console.log("result:");
// return list;
/** try 2
*/
// let list = {};
//
// for (let i = array.length - 1; i >= 0; i--) {
// list.rest = list;
// list.value = array[i];
// }
// return list;
/** try 3
Every loop creates a new list object containing the old one.
But i still dont see why my tries above don't work.
*/
let list = {};
for (let i = array.length - 1; i >= 0; i--) {
list = {
value: array[i],
rest: list
}
// console.log(list);
}
return list;
}
/***
An other possibility that relate more to my thought process. Given to me on stackoverflow
function arrayToListTry4 (array) {
let list = {}
for (let i = array.length - 1; i >= 0; i--) {
list.rest = Object.assign({}, list);
list.value = array[i];
}
return list
}
**/
function listToArray (list){
let arr = [];
while (list.rest !== undefined ) {
arr.push(list.value);
list = list.rest;
// console.log(list);
// console.log(arr);
}
return arr;
}
function prepend (item, list){
return { value: item, rest: list};
}
function nth (list, nth){
for (var i = 0; i < nth -1; i++) {
list = list.rest
}
return list.value
}
function recNth (list, nth){
if (nth - 1 == 0) {
return list.value;
} else {
return recGetNth(list.rest, nth -1);
}
}
console.log(arrayToList(arrayValue));
// → { value: 'hello',
rest: { value: 'world', rest: { value: '!!!', rest: {} } } }
console.log(listToArray(list));
// → [ 'hello', 'world', '!!!' ]
console.log(listToArray(arrayToList(arrayValue)));
// → [ 'hello', 'world', '!!!' ]
console.log(arrayToList(listToArray(listValue)));
// → { value: 'hello',
rest: { value: 'world', rest: { value: '!!!', rest: {} } } }
console.log(prepend("Hey", listValue));
// → { value: 'Hey',
rest: { value: 'hello', rest: { value: 'world', rest: { value: '!!!', rest: {} } } } }
console.log(nth(listValue, 3));
// → "!!!"
console.log(recNth(listValue, 2));
// → "world"
最佳答案
在 list.rest = list;
中,您将 list.rest 属性设置回其自身的引用,这就是它显示“Circular”的原因。这是因为在 Javascript 中,Objects and Arrays are passed by reference 。
您想要做的是创建原始元素的深拷贝。您可以通过几种方式做到这一点:
JSON.parse(JSON.stringify(list))
将在 JSON 之间进行解构(保留所有键和所有对象深度)。或者,Object.assign({}, list)
会将对象的所有第一级键分配给新对象。这意味着像这样的对象:
{
root: {
inner: "test",
}
}
只会分配root
键,但inner
在执行Object.assign
时不会被复制
因此,您的解决方案是:
for (let i = array.length - 1; i >= 0; i--) {
list.rest = Object.assign({}, list);
list.value = array[i];
}
或
for (let i = array.length - 1; i >= 0; i--) {
list.rest = JSON.parse(JSON.stringify(list));
list.value = array[i];
}
关于javascript - 我不明白 Eloquent js "a list"练习(我有一些奇怪的结果),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58509322/
我是一名优秀的程序员,十分优秀!