【问题标题】:JavaScript, Can only access property using underscore _JavaScript,只能使用下划线 _ 访问属性
【发布时间】:2019-07-21 19:41:13
【问题描述】:

我一直在编写代码来构建嵌套/递归对象/数组树。将 getter/setter 添加到对象后,我只能使用“_”前缀访问树根中的属性。见代码的第 89 行,几乎在底部,console.logs 开始的地方。

// My intention is to create a single “template” object definition that can be used to build a tree of sline / leaves of the same object.
// Also functions are created that can get/set values of any properties for any leaf using an array representing the position of the leaf in the tree.

// Create Sline/Leaf Object Template
class objTemplate {
    constructor(SpineName, Width, Height) {
        this.SpineName = SpineName;
        this.Width = Width;
        this.Height = Height;
        this.Area;
        this.Leaves = [];
    }

    get SpineName() {
        return this._SpineName;
    }

    set SpineName(value) {
        if (value.length === 0) {
            console.log("Sline Name Is Required.");
            return;
        }
        this._SpineName = value;
    }

    get Width() {
        return this._Width;
    }

    set Width(value) {
        this._Width = value;
        this._Area = this._Width * this._Height;
    }

    get Height() {
        return this._Height;
    }

    set Height(value) {
        this._Height = value;
        this._Area = this._Width * this._Height;
    }

    get Area() {
        return this._Area;
    }

}

// Push Leaf bject To Tree 
function pushLeaf(Position, Tree, NewLeaf) {
    Position.reduce((val, prop) => { return val.Leaves[prop]; }, Tree).Leaves.push(NewLeaf);
}

// Get Value From Leaf Object 
function getValue(Position, Tree, Key) {
    return Position.reduce((val, prop) => { return val.Leaves[prop]; }, Tree)[Key];
}

// Set Leaf Object Value 
function setValue(Position, Tree, Key, value) {
    Position.reduce((val, prop) => { return val.Leaves[prop]; }, Tree)[Key] = value;
}

// Create Initial Tree
var objTree = Object.assign(Object.create(Object.getPrototypeOf(objTemplate)), new objTemplate("Root", 4, 5));

// Add Under Root Object
pushLeaf([], objTree, new objTemplate("Oreo", 3, 4));
pushLeaf([], objTree, new objTemplate("Jupiter", 7, 3));

// Add Under Root / 1st Object 
pushLeaf([0], objTree, new objTemplate("Moonman", 5, 2));
pushLeaf([0], objTree, new objTemplate("Slade", 4, 4));
pushLeaf([0], objTree, new objTemplate("Bubba", 4, 6));

// Add Under Root / 2nd Object
pushLeaf([0], objTree, new objTemplate("Chicken Butt", 9, 5));
pushLeaf([0], objTree, new objTemplate("Boss", 3, 5));

// Add Under Root / 1st Object / 3rd Object
pushLeaf([[0], [2]], objTree, new objTemplate("Buddy", 6, 4));
pushLeaf([[0], [2]], objTree, new objTemplate("Roe", 4, 8));

// Add Under Root / 1st Object / 3rd Object / 2nd Object
pushLeaf([[0], [2], [1]], objTree, new objTemplate("Little Man", 6, 4));


console.log(`Root Object Spine Name: ${getValue([], objTree, "_SpineName")}`); // Where getters/setter are used, on root "_" prefx must be used for the property name
console.log(`Root Object / 1st Object Spine Name: ${getValue([0], objTree, "SpineName")}`);
console.log(`Root Object / 2nd Object Spine Name: ${getValue([1], objTree, "SpineName")}`);
console.log(`Root Object / 1st Object / 3rd object Spine Name: ${getValue([[0], [2]], objTree, "SpineName")}`);
console.log("");

console.log(`Root Object / 1st Object / 3rd object / 2nd Object Width: ${getValue([[0], [2], [1]], objTree, "Width")}`);
console.log(`Root Object / 1st Object / 3rd object / 2nd Object Height: ${getValue([[0], [2], [1]], objTree, "Height")}`);
console.log(`Root Object / 1st Object / 3rd object / 2nd Object Area: ${getValue([[0], [2], [1]], objTree, "Area")}`);
console.log("");

console.log('Change Root Object / 1st Object / 3rd object / 2nd Object Width:');
setValue([[0], [2], [1]], objTree, "Width", 8);
console.log(`Root Object / 1st Object / 3rd object / 2nd Object Width: ${getValue([[0], [2], [1]], objTree, "Width")}`);
console.log(`Root Object / 1st Object / 3rd object / 2nd Object Height: ${getValue([[0], [2], [1]], objTree, "Height")}`);
console.log(`Root Object / 1st Object / 3rd object / 2nd Object Area: ${getValue([[0], [2], [1]], objTree, "Area")}`);

//console.log(JSON.stringify(objTree));

同样,这仅在添加 getter/setter 后才出现。为了统一,我也可以在调用树中其他位置的对象的所有属性时使用“_”前缀。但我不知道这是否可以接受?或者还有什么不同的做法?也许有一种不同的方式可以一起完成我想要实现的目标?

【问题讨论】:

  • 我不明白这个问题。它应该打印什么,它打印的是什么?

标签: javascript arrays recursion nested javascript-objects


【解决方案1】:

您使用Object.assign()Object.create() 创建objTree 的方式未正确复制原型。

如果您将其更改为:

var objTree = new objTemplate("Root", 4, 5);

它将按需要工作。这就是您创建所有嵌套对象的方式,我认为没有任何理由以不同的方式创建根。

// My intention is to create a single “template” object definition that can be used to build a tree of sline / leaves of the same object.
// Also functions are created that can get/set values of any properties for any leaf using an array representing the position of the leaf in the tree.

// Create Sline/Leaf Object Template
class objTemplate {
    constructor(SpineName, Width, Height) {
        this.SpineName = SpineName;
        this.Width = Width;
        this.Height = Height;
        this.Area;
        this.Leaves = [];
    }

    get SpineName() {
        return this._SpineName;
    }

    set SpineName(value) {
        if (value.length === 0) {
            console.log("Sline Name Is Required.");
            return;
        }
        this._SpineName = value;
    }

    get Width() {
        return this._Width;
    }

    set Width(value) {
        this._Width = value;
        this._Area = this._Width * this._Height;
    }

    get Height() {
        return this._Height;
    }

    set Height(value) {
        this._Height = value;
        this._Area = this._Width * this._Height;
    }

    get Area() {
        return this._Area;
    }

}

// Push Leaf bject To Tree 
function pushLeaf(Position, Tree, NewLeaf) {
    Position.reduce((val, prop) => { return val.Leaves[prop]; }, Tree).Leaves.push(NewLeaf);
}

// Get Value From Leaf Object 
function getValue(Position, Tree, Key) {
    return Position.reduce((val, prop) => { return val.Leaves[prop]; }, Tree)[Key];
}

// Set Leaf Object Value 
function setValue(Position, Tree, Key, value) {
    Position.reduce((val, prop) => { return val.Leaves[prop]; }, Tree)[Key] = value;
}

// Create Initial Tree
var objTree = new objTemplate("Root", 4, 5);

// Add Under Root Object
pushLeaf([], objTree, new objTemplate("Oreo", 3, 4));
pushLeaf([], objTree, new objTemplate("Jupiter", 7, 3));

// Add Under Root / 1st Object 
pushLeaf([0], objTree, new objTemplate("Moonman", 5, 2));
pushLeaf([0], objTree, new objTemplate("Slade", 4, 4));
pushLeaf([0], objTree, new objTemplate("Bubba", 4, 6));

// Add Under Root / 2nd Object
pushLeaf([0], objTree, new objTemplate("Chicken Butt", 9, 5));
pushLeaf([0], objTree, new objTemplate("Boss", 3, 5));

// Add Under Root / 1st Object / 3rd Object
pushLeaf([[0], [2]], objTree, new objTemplate("Buddy", 6, 4));
pushLeaf([[0], [2]], objTree, new objTemplate("Roe", 4, 8));

// Add Under Root / 1st Object / 3rd Object / 2nd Object
pushLeaf([[0], [2], [1]], objTree, new objTemplate("Little Man", 6, 4));


console.log(`Root Object Spine Name: ${getValue([], objTree, "SpineName")}`); // Where getters/setter are used, on root "_" prefx must be used for the property name
console.log(`Root Object / 1st Object Spine Name: ${getValue([0], objTree, "SpineName")}`);
console.log(`Root Object / 2nd Object Spine Name: ${getValue([1], objTree, "SpineName")}`);
console.log(`Root Object / 1st Object / 3rd object Spine Name: ${getValue([[0], [2]], objTree, "SpineName")}`);
console.log("");

console.log(`Root Object / 1st Object / 3rd object / 2nd Object Width: ${getValue([[0], [2], [1]], objTree, "Width")}`);
console.log(`Root Object / 1st Object / 3rd object / 2nd Object Height: ${getValue([[0], [2], [1]], objTree, "Height")}`);
console.log(`Root Object / 1st Object / 3rd object / 2nd Object Area: ${getValue([[0], [2], [1]], objTree, "Area")}`);
console.log("");

console.log('Change Root Object / 1st Object / 3rd object / 2nd Object Width:');
setValue([[0], [2], [1]], objTree, "Width", 8);
console.log(`Root Object / 1st Object / 3rd object / 2nd Object Width: ${getValue([[0], [2], [1]], objTree, "Width")}`);
console.log(`Root Object / 1st Object / 3rd object / 2nd Object Height: ${getValue([[0], [2], [1]], objTree, "Height")}`);
console.log(`Root Object / 1st Object / 3rd object / 2nd Object Area: ${getValue([[0], [2], [1]], objTree, "Area")}`);

//console.log(JSON.stringify(objTree));

【讨论】:

  • 谢谢...是的,这行得通。这部分是最初尝试实现这一点时遗留下来的。但我现在明白为什么不再需要它了。
猜你喜欢
  • 2011-11-14
  • 1970-01-01
  • 2013-05-22
  • 1970-01-01
  • 2017-06-12
  • 2013-03-26
  • 2012-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多