如何直接分配或继承对象属性?

时间:2013-07-05 20:56:48

标签: javascript oop object

我有一个带默认值的构造函数:

var myObject = function(){
    this.myValue = "default";
}

然后我实例化一个新对象:

var newInstance = new myObject();

如何判断myValue是否为原始默认值,并且尚未重新分配。我无法检查该值,因为它可以设置为相同,并且会产生误报。

3 个答案:

答案 0 :(得分:5)

使用Object.hasOwnProperty()

if (newInstance.hasOwnProperty('myValue')) {
    // original default value
}

然而,这将无法告诉您这是否发生:

newInstance.myValue = 'default';

要检测到这一点,您需要使用getters/setters之类的内容并跟踪私有变异标记:

function myObject() {
    var _myValue = "default";
    var _wasMutated = false;

    return {
        get myValue() {
            return _myValue;
        },
        set myValue(x) {
            _myValue = x;
            _wasMutated = true;
        },
        get wasMutated() {
            return _wasMutated;
        }
    }
}

// usage:
var newInstance = new myObject();
newInstance.myValue;                // "default"
newInstance.wasMutated;             // false
newInstance.myValue = "default";
newInstance.wasMutated;             // true
newInstance.wasMutated = false;     // writes have no effect since there's no setter
newInstance.wasMutated;             // true

答案 1 :(得分:2)

  

我无法检查该值,因为它可能设置为相同,并且会产生误报。

如果您将构造函数更改为而不是设置该值,而是将其设置在原型上:

var myObject = function(){};
myObject.prototype.myValue = "default";

...然后您可以使用.hasOwnProperty() method来测试myValue是否已被覆盖,即使它已被设置为与默认值相同的值。

if (!newInstance.hasOwnProperty("myValue")) {
    // has not been assigned another value
}

这是有效的,因为如果你以后说:

newInstance.myValue = "something";

...它将直接在实例上创建myValue属性。当你使用newInstance .myValue时,它会自动检索直接属性(如果存在)或者继承原型属性。

var newInstance = new myObject();

console.log( newInstance.myValue );                   // "default"
console.log( newInstance.hasOwnProperty("myValue") ); // false

newInstance.myValue = "default";
console.log( newInstance.myValue );                   // "default"
console.log( newInstance.hasOwnProperty("myValue") ); // true

答案 2 :(得分:1)

没有内置的方法来完成你正在寻找的东西,但是使用“默认”对象很容易:

var MyObject = function() {
    this.myValue = this.defaults.myValue
}
MyObject.prototype.defaults = { myValue: 'default' };
MyObject.prototype.isDefault = function(prop) { 
    return this[prop]===this.defaults[prop];
}

var o = new MyObject();
o.isDefault('myValue');   // returns true
o.myValue = 'foo';
o.isDefault('myValue');   // returns false
o.myValue = 'default';
o.isDefault('myValue');   // returns true

另一方面,如果你需要知道的是是否曾经设置了一个属性(无论它的值是多少),你将不得不使用私有属性和getter / setter函数:

var MyObject = function() {
    var myValue = 'default';       // i'm private!
    var myValueHasChanged = false;
    this.myValue = function(newVal) {
        if( arguments.length===0 ) {
            return newVal;
        } else {
            myValue = newVal;
            myValueHasChanged = true;
        }
    }
    this.myValueHasChanged = function() {
        return myValueHasChanged;
    }
}

var o = new MyObject();
o.myValue();              // returns 'default'
o.myValueHasChanged();    // returns false
o.myValue('foo');
o.myValue();              // returns 'foo'
o.myValueHasChanged();    // returns true
o.myValue('default');
o.myValueHasChanged();    // returns true