访问类变量

时间:2018-03-12 16:48:54

标签: javascript

我想访问一个类变量。但是在构造函数中分配数据。 EX:

class Student {
    constructor(data) {
       this.data = data;
       this.extraVariable = "Value"
    }

    getData() {
       return this.data
    }
}

var s = new Student({name: 'Abcd', subject: 'Javascript'});

s.name = 'Xyz';  // i want to access name using s.name not s.data.name

// i want to get updated data by calling this
s.getData() // it return { name: 'Xyz', subject: 'Javascript' }

在这个类中在构造函数或setData方法中分配数据但我想直接访问这些数据而不使用this.data.variableName。当我调用getData方法

时,我想只获取那些数据,而不是其他类变量

注意:该成员不应像名称和主题那样修复。如果我想添加更多成员,我不想创建getName和setName方法,因为成员不是固定的

5 个答案:

答案 0 :(得分:2)

正如@Hammerbot已经暗示的那样,你可以迭代对象并将每个属性应用于当前实例:



class Student {
  constructor(data) {
    this.data = data;
    this.extraVariable = "Value";
    
    // Assign each property of the object directly to the instance
    Object.keys(data).forEach((key) => {
      this[key] = data[key];
    });
  }

  getData() {
    return this.data
  }
}

var s = new Student({name: 'Abcd', subject: 'Javascript'});

s.name = 'Xyz';

console.log(s.name);




原始答案:创建getter和setter

您可以在name的课程中添加getter和setter。这些getter和setter将引用this.data.name,但会提供您正在寻找的交互:



class Student {
  constructor(data) {
    this.data = data;
    this.extraVariable = "Value"
  }

  getData() {
    return this.data
  }

  get name() {
    return this.data.name;
  }

  set name(name) {
    this.data.name = name;
  }
}

var s = new Student({name: 'Abcd', subject: 'Javascript'});

s.name = 'Xyz';

console.log(s.name);




答案 1 :(得分:1)

我不确定我是否理解你的问题,但就我而言,id说你可以用这种方式使用getter和setter。

class Student {
    constructor(data) {
       this.data = data;
       this.extraVariable = "Value"
    }

    get name() {
      return this.data.name
    }
    set name(val) {
     this.data.name = val
    }
    get subject() {
      return this.data.name
    }
    set subject(val) {
     this.data.subject = val
    }

    getData() {
       return this.data
    }
}

var s = new Student({name: 'Abcd', subject: 'Javascript'});

s.name = 'Xyz';
s.name // 'Xyz'

当然代码还没有完成。它需要验证,因为data属性可能未定义,您将收到错误。

虽然它可以解决您解决的问题,但我会采用另一种方式,通过定义这些内部属性并直接设置它们。

修改 因此,由于需要动态吸气剂,我会这样:

...
getProp(propName) {
    return this.data[propName]
}

setProp(propName, value) {
    this.data[propName] = value
}
...

答案 2 :(得分:1)

这是正确的面向对象方法。



class Student {
  constructor(configuration) {
    configuration = configuration || {}
    this.name = configuration.name
    this.subject = configuration.subject
    this.extraVariable = "Value"
  }

  setName(name) { this.name = name }
  getName() { return this.name }
  
  setSubject(subject) { this.subject = subject }
  getSubject() { return  this.subject }

  getData() {
    return {
      name: this.getName(),
      subject: this.getSubject()
    }
  }
}

let student = new Student({
  name: 'Abcd',
  subject: 'Javascript'
})

student.setName('Xyz')

console.log(student.getData())

.as-console-wrapper { top: 0; max-height: 100% important! }




动态版

如果要动态创建和获取字段,则需要创建一个委托字段来存储数据,例如this.fields。请参阅下面的修改后的代码。



function extend(originalObject, newData) {
  for (var key in newData) {
    originalObject[key] = newData[key]
  }
}
function isFunction(obj) { return obj && typeof obj === 'function'; }

class Student {
  constructor(configuration) {
    this.fields = {
      extraVariable: "Value"
    }
    extend(this.fields, configuration || {})
  }
  
  setField(field, value) { this.fields[field] = value }
  getField(field) { return this.fields[field] }
  
  removeField(field) {
    if (this.fields.hasOwnProperty(field)) {
      delete this.fields[field];
      return true;
    }
    return false;
  }
  
  getData() {
    let fields = this.fields;
    return Object.keys(fields).reduce(function(obj, field) {
      if (!isFunction(fields[field])) {
        obj[field] = fields[field]
      }
      return obj
    }, {})
  }
}

let student = new Student({ name: 'Abcd', subject: 'Javascript' })

student.setField('name', 'Xyz') // Update field
student.removeField('subject')  // Remove Field

console.log(student.getData())

.as-console-wrapper {
  top: 0;
  max-height: 100% important!
}




答案 3 :(得分:0)

你也可以做这样的事情,但我发现它非常hacky,我更喜欢@KevBot答案:

class Student {
    constructor(data) {
        this.authorized = Object.keys(data)
        this.authorized.forEach(key => {
            this[key] = data[key]
        })
        this.extraVariable = "Value"
    }

    getData() {
        let data = {}
        this.authorized.forEach(key => {
            data[key] = this[key]
        })
        return data
    }
}

答案 4 :(得分:0)

如果我得到了你想要做的事情,以下应该可以解决问题:

class Student {
    constructor( data ) {
        this.data = data;
        this.extraVariable = "Value";
    }


    getData() {
        // Updates the modified properties only .
        for( var prop in this) {
            if ( this.hasOwnProperty( prop ) ) {
                if (this.data[prop]) {
                    this.data[prop] = this[prop];
                }
            }
        }

        return this.data;
    }
}

你可以分开这样的事情:

class Student {
    constructor( data ) {
        this.data = data;
        this.extraVariable = "Value";
    }

    // Updates the modified properties only .
    updateData() {
        for( var prop in this) {
            if ( this.hasOwnProperty( prop ) ) {
                if (this.data[prop]) {
                    this.data[prop] = this[prop];
                }
            }
        }
    }

    getData() {
        this.updateData();
        return this.data;
    }
}

就是这样,你可以传递任何你想要的东西:

var s = new Student({name: 'Abcd', subject: 'Javascript'});
s.name = 'Xyz';
s.getData();

var s2 = new Student({firstname: 'Abcd', class: 'Computer science'});
s2.firstname = 'Xyz';
s2.getData();