将 undefined 作为对象处理
Handle undefined as an object
是否有一种技术/框架,可以在将新对象作为对象处理时创建并将其存储到未定义的变量中?
F.e。写作
some.thing = 7;
给出错误描述,无法设置未定义的(某些)属性。
所以现在,我们要回去写
some = {};
some.thing = 7;
这看起来 几乎 对我来说是不必要的,因为很明显,我想使用一些作为对象。
这样会很舒服:
hospitals.sectors.doctors = [];
hospitals.sectors.doctors[ 0 ].age = 32;
这看起来比
更高效、更简单
hospitals = {};
hospitals.sectors = {};
hospitals.sectors.doctors = [];
hospitals.sectors.doctors[ 0 ] = {};
hospitals.sectors.doctors[ 0 ].age = 32;
您可以编写自己的处理程序来完成这项工作
function createObjectProperty(objNameString, objPropertyString, objValueString) {
window[objNameString] = {};
window[objNameString][objPropertyString] = objValueString;
return window[objNameString];}
var test = createObjectProperty("some", "thing", 7);
alert(test.thing);
调用看起来像:
createObjectProperty("some", "thing", 7);
并提示“7”。您还可以在创建新对象之前检查它是否存在。我会遍历对象并收集所有属性,检查重复项并在需要此类功能时附加我的新属性+值。否则新对象将覆盖旧对象。希望这就是您正在寻找的东西
工作fiddle(更新):
如果您尝试将 7
分配给 some.thing
并且 some
应该 不 事先声明,请使用 Cory 的建议var some = { thing: 7 };
.
如果您尝试将 7
分配给 some.thing
并且 some
可能 已经是 declared/defined(或者即使它已声明,可能会或可能不会设置为 undefined
),使用
(some = (some || {})).thing = 7;
或(一个更具可读性的解决方案,虽然不是一个班轮)
some = (some || {});
some.thing = 7;
我的解决方案的一个警告是,如果未提前声明,您可能会在 some
上获得不需要的范围。未定义但仍声明的示例(因此范围将是预期的):
function assignThing(some) {
(some = (some || {})).thing = 7; /* one liner solution */
return some;
}
var foo = assignThing(); /* the parameter 'some' is undefined, but declared */
var bar = assignThing({}); /* the parameter 'some' is defined
* (though empty) and declared */
(baz = (baz || {})).thing = 7; /* Unless you have this declared
* elsewhere this *should* be the
* global scope */
var foobar; /* declared, not defined */
(foobar = (foobar || {})).thing = 7; /* now defined */
编辑:创建了一个像 anddoutoi 建议的名称空间解决方案。
第一个用法示例 (hospitals
) 使用第三个参数的可选性质,默认为 "undefined".
第二个示例 (hospitals2
) 通过未定义。
第三个例子(hospitals3
)传递了另一个对象(我碰巧是内联创建的)。
对于您(OP)提供的示例,我的 hospitals
示例最接近完全匹配。除了使用规范名称字符串 + 函数之外,我不知道有什么方法可以自动神奇地创建对象层次结构。
function create(canonicalPropertyName, value, root) {
root = (root || {});
var names = canonicalPropertyName.split(".");
var current = root;
for (var i = 0; i < names.length; i++) {
/* Ensure the property exists */
current[names[i]] = (current[names[i]] || (i < names.length - 1 ? {} : []));
/* We're recursing down the object tree */
current = current[names[i]];
}
return root;
}
var hospitals = create("sectors.doctors", []);
hospitals.sectors.doctors[ 0 ] = {};
hospitals.sectors.doctors[ 0 ].age = 32;
console.log(hospitals);
var hospitals2 = create("sectors.doctors", [], undefined);
hospitals2.sectors.doctors[ 0 ] = {};
hospitals2.sectors.doctors[ 0 ].age = 32;
console.log(hospitals2);
var hospitals3 = create("sectors.doctors", [], { name: "City Hospital" });
hospitals3.sectors.doctors[ 0 ] = {};
hospitals3.sectors.doctors[ 0 ].age = 32;
console.log(hospitals3);
许多框架都有一个 namespace()
method/function 可以帮助您实现您想要的。
- http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_namespace
- https://docs.sencha.com/extjs/5.1/5.1.1-apidocs/#!/api/Ext-method-namespace
示例:
Ext.ns('hospitals.sectors.doctors') = [];
var doctors = Ext.ns('hospitals.sectors.doctors');
doctors[0] = {
age : 32
};
我自己不喜欢这种模式,因为它增加了不必要的依赖和工作。
是否有一种技术/框架,可以在将新对象作为对象处理时创建并将其存储到未定义的变量中?
F.e。写作
some.thing = 7;
给出错误描述,无法设置未定义的(某些)属性。
所以现在,我们要回去写
some = {};
some.thing = 7;
这看起来 几乎 对我来说是不必要的,因为很明显,我想使用一些作为对象。
这样会很舒服:
hospitals.sectors.doctors = [];
hospitals.sectors.doctors[ 0 ].age = 32;
这看起来比
更高效、更简单hospitals = {};
hospitals.sectors = {};
hospitals.sectors.doctors = [];
hospitals.sectors.doctors[ 0 ] = {};
hospitals.sectors.doctors[ 0 ].age = 32;
您可以编写自己的处理程序来完成这项工作
function createObjectProperty(objNameString, objPropertyString, objValueString) {
window[objNameString] = {};
window[objNameString][objPropertyString] = objValueString;
return window[objNameString];}
var test = createObjectProperty("some", "thing", 7);
alert(test.thing);
调用看起来像:
createObjectProperty("some", "thing", 7);
并提示“7”。您还可以在创建新对象之前检查它是否存在。我会遍历对象并收集所有属性,检查重复项并在需要此类功能时附加我的新属性+值。否则新对象将覆盖旧对象。希望这就是您正在寻找的东西
工作fiddle(更新):
如果您尝试将 7
分配给 some.thing
并且 some
应该 不 事先声明,请使用 Cory 的建议var some = { thing: 7 };
.
如果您尝试将 7
分配给 some.thing
并且 some
可能 已经是 declared/defined(或者即使它已声明,可能会或可能不会设置为 undefined
),使用
(some = (some || {})).thing = 7;
或(一个更具可读性的解决方案,虽然不是一个班轮)
some = (some || {});
some.thing = 7;
我的解决方案的一个警告是,如果未提前声明,您可能会在 some
上获得不需要的范围。未定义但仍声明的示例(因此范围将是预期的):
function assignThing(some) {
(some = (some || {})).thing = 7; /* one liner solution */
return some;
}
var foo = assignThing(); /* the parameter 'some' is undefined, but declared */
var bar = assignThing({}); /* the parameter 'some' is defined
* (though empty) and declared */
(baz = (baz || {})).thing = 7; /* Unless you have this declared
* elsewhere this *should* be the
* global scope */
var foobar; /* declared, not defined */
(foobar = (foobar || {})).thing = 7; /* now defined */
编辑:创建了一个像 anddoutoi 建议的名称空间解决方案。
第一个用法示例 (hospitals
) 使用第三个参数的可选性质,默认为 "undefined".
第二个示例 (hospitals2
) 通过未定义。
第三个例子(hospitals3
)传递了另一个对象(我碰巧是内联创建的)。
对于您(OP)提供的示例,我的 hospitals
示例最接近完全匹配。除了使用规范名称字符串 + 函数之外,我不知道有什么方法可以自动神奇地创建对象层次结构。
function create(canonicalPropertyName, value, root) {
root = (root || {});
var names = canonicalPropertyName.split(".");
var current = root;
for (var i = 0; i < names.length; i++) {
/* Ensure the property exists */
current[names[i]] = (current[names[i]] || (i < names.length - 1 ? {} : []));
/* We're recursing down the object tree */
current = current[names[i]];
}
return root;
}
var hospitals = create("sectors.doctors", []);
hospitals.sectors.doctors[ 0 ] = {};
hospitals.sectors.doctors[ 0 ].age = 32;
console.log(hospitals);
var hospitals2 = create("sectors.doctors", [], undefined);
hospitals2.sectors.doctors[ 0 ] = {};
hospitals2.sectors.doctors[ 0 ].age = 32;
console.log(hospitals2);
var hospitals3 = create("sectors.doctors", [], { name: "City Hospital" });
hospitals3.sectors.doctors[ 0 ] = {};
hospitals3.sectors.doctors[ 0 ].age = 32;
console.log(hospitals3);
许多框架都有一个 namespace()
method/function 可以帮助您实现您想要的。
- http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_namespace
- https://docs.sencha.com/extjs/5.1/5.1.1-apidocs/#!/api/Ext-method-namespace
示例:
Ext.ns('hospitals.sectors.doctors') = [];
var doctors = Ext.ns('hospitals.sectors.doctors');
doctors[0] = {
age : 32
};
我自己不喜欢这种模式,因为它增加了不必要的依赖和工作。