我正在编写一个AngularJS服务提供程序(函数):
服务查询不同的表(具有不同的列),因此result
对象具有不同的属性 - 具体取决于数据源自哪个表。
Object.defineProperties
用于特定的对象属性,因为我不知道在创建查询“case”之前的属性当对象返回到控制器功能时,需要进行一些操作
writable: true
)writable: false
问题:
如何为对象的所有(未来)属性定义一个具有属性configurable: true, writable: true, enumerable: true
的对象?即如何设置对象的默认属性,因为我不(还)知道对象的确切属性名称?
示例代码:
this.checkRowExists = function(table, id) {
try {
var deferred = $q.defer();
switch (table) {
case "table1" :
var selectQuery = 'SELECT * FROM ' + table + ' WHERE id=?';
break;
case "table2" :
var selectQuery = 'SELECT * FROM ' + table + ' WHERE id=?';
break;
case "table3" :
var selectQuery = 'SELECT * FROM ' + table + ' WHERE id=?';
break;
}
this.db.transaction(function(tx) {
tx.executeSql(selectQuery, [id], function(tx, results) {
if (results.rows.length > 0){
var myRow = {}; // <- how to define all properties in "myRow" object as configurable and writable ??
var myRow = results.rows.item(0);
deferred.resolve(myRow); // <- object "myRow" is returned here to various controller functions
} else {
deferred.resolve(results.rows.length);
}
}, function(tx, error) {
console.log('checkRowExists: Error occurred while searching for profile.', error);
deferred.reject(error);
});
});
return deferred.promise;
} catch(exception) {
console.log('checkRowExists: Error occurred while trying this function.', exception);
}
};
PS代码工作正常,但只返回writable: false, enumerable: true, configurable: false
的对象,而我需要一切true
编辑:
即使在以下部分解决方案后仍存在问题:
- 为什么不能使用Object.defineProperty
方法手动更改属性描述符?
- 当默认值为false时,为什么enumerable: true
?这与SQlite数据库事务有关吗?
- 为什么writable: false, enumerable: false, configurable: false
的默认值没有应用于使用JSON方法克隆的新对象?
答案是here - 取决于对象的创建方式 - 请参阅下面的评论
答案 0 :(得分:0)
问题的一半似乎是对象myRow
继承了从中复制的对象的属性描述符/属性,即:
var myRow = results.rows.item(0)
问题的另一半是,似乎无法改变属性描述符:
即使用Object.defineProperty(myRow, "my_property", {configurable: true});
- &GT;给出TypeError: Cannot redefine property: my_property
部分解决方案
根据{{3}}中的第3个答案,克隆对象最优雅的方法是使用:
var newObject = JSON.parse(JSON.stringify(oldObject));
这似乎创造了一个全新的对象,它不会从“复制”中继承属性描述符。对象
无论出于何种原因,都会产生一个具有
的物体
writable: true, enumerable: true, configurable: true
(在Chrome和Safari中测试过)
(对于this discussion中列出的所有3个描述符的false
的默认值,这是没有意义的)
修改强>
这是因为对象的定义方式 - 请参阅spec
- 定义为myObject={}; myObject.a=1;
所有属性描述符默认为true,
- 定义为Object.defineProperty(myObject, 'a', { value: 1 });
任何未定义的描述符默认为false
所以上面代码中以下代码段的输出如下所示:
tx.executeSql(selectQuery, [id], function(tx, results) {
if (results.rows.length > 0){
// see what the original object descriptors are set at:
console.log( Object.getOwnPropertyDescriptor(results.rows.item(0), "my_property") );
// -> outputs "configurable: false, enumerable: true, writable: false"
var myRow = results.rows.item(0);
// see what the new copied object descriptors are set at:
console.log( Object.getOwnPropertyDescriptor(myRow, "my_property") );
// -> outputs "configurable: false, enumerable: true, writable: false"
var myRow2 = JSON.parse(JSON.stringify(results.rows.item(0)));
// see what the new JSON cloned object descriptors are set at:
console.log( Object.getOwnPropertyDescriptor(myRow, "my_property") );
// -> outputs "configurable: true, enumerable: true, writable: true"
deferred.resolve(myRow2);
} else {
deferred.resolve(results.rows.length);
}
}, function(tx, error) {
console.log('checkRowExists: Error occurred while searching for profile.', error);
deferred.reject(error);
});
对这个部分解决方案仍然有几个问题:
- 使用JSON.parse(JSON.stringify(object));
复制/克隆对象的速度是多少?
- 使用JSON.parse(JSON.stringify(object));
进行克隆有其他缺点吗?
(有些列出here - 大部分都不适用于对象属性中的日期格式或函数)