1

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

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

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

var newInstance = new myObject();

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

4

3 回答 3

5

使用Object.hasOwnProperty().

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

但是,这将无法告诉您是否发生了这种情况:

newInstance.myValue = 'default';

要检测到这一点,您需要使用getter/setter 之类的东西并跟踪私有突变标志:

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
于 2013-07-05T20:58:44.857 回答
2

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

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

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

...然后您可以使用该.hasOwnProperty()方法测试是否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
于 2013-07-05T21:11:06.380 回答
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
于 2013-07-05T21:05:04.540 回答