首先要说明的是,继承DynamicObject的类(当然是在C#中)与JavaScript的变量是动态的不同。DynamicObject允许实现者以编程方式确定对象有哪些成员,包括方法。
编辑:我知道JavaScript对象可以在运行时向它们添加任何成员。我说的完全不是这个。下面是一个C#示例,展示了DynamicObject的功能:
public class SampleObject : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = binder.Name;
return true;
}
}
dynamic obj = new SampleObject();
Console.WriteLine(obj.SampleProperty);
//Prints "SampleProperty".当访问obj的成员时,它使用TryGetMember以编程方式确定该成员是否存在及其值。简而言之,成员的存在是在请求时确定的,而不是在手动之前添加。我希望这能澄清一些问题。如果您想知道,我正在尝试确定是否可以在JavaScript中创建一个对象,当函数调用语法在其上使用时,如下所示:
myAPI.uploadSomeData(data1, data2)uploadSomeData调用转到类似于"TryGetMember“的函数,该函数使用名称"uploadSomeData”来执行$.ajax调用,结果是返回值。
发布于 2012-09-16 15:37:55
发布于 2012-08-27 23:10:19
JavaScript允许在for...in循环中迭代对象的属性和方法。您可以确定它是否是使用typeof运算符的方法。
HTML:
<ul id="console"></ul>
JavaScript:
var Application = (function(app) {
app.constants = app.constants || {};
app.constants.PRINT_OBJ_TITLE = '[Printing an object]';
app.console = {
constants: {
SEPARATOR: new Array(50).join('-')
},
output: document.getElementById('console'),
log: function() {
var li = document.createElement('li');
li.innerHTML = Array.prototype.join.call(arguments, '');
this.output.appendChild(li);
},
printSeparator: function() {
this.log(this.constants.SEPARATOR);
}
};
app.printObj = function(obj) {
this.console.log(app.constants.PRINT_OBJ_TITLE);
for(var prop in obj) {
if(obj.hasOwnProperty(prop)) {
var propType = (typeof obj[prop] == 'function')
? 'function'
: 'property';
this.console.log(propType, ': ', prop);
}
}
this.console.printSeparator();
};
return app;
})(Application || {});
var obj = {},
app = Application;
obj.foo = function() {
alert("I'm a foo function!");
};
obj.bar = "I'm just a property";
app.printObj(obj);演示
更新
因此,您不应该期望JavaScript有如此多的反射工具,比如Java或C#。您可以在某种程度上模拟这种行为,但无论如何,您将不能只创建特殊的JavaScript对象并调用其不存在的属性。唯一的方法是创建一个特殊的函数来实现开关、外观、地图等--任何允许使流更加动态的结构。
就像这样的前枫树。
您可以改进这一逻辑,并根据用户的操作、传入的数据等添加额外的属性和功能到app.Stuff上。因此,总的来说,您可以使用JavaScript中的某种元编程来构建智能和灵活的系统。
发布于 2019-05-10 10:01:29
我堆叠了类似的问题,并编写了以下代码:
const dynamicFunc = (input) => {
const handler = {
get: (obj, prop) => {
// edge case when .toString() is calling for dynamic prop - just return any string
if (typeof prop === 'symbol') {
return () => "custom_dynamic_str";
}
const isPropExist = typeof obj[prop] !== 'undefined';
if (isPropExist) {
const val = obj[prop];
// if null or undefined was set
if (val == null || typeof val === 'undefined') {
return val;
}
// if value was created not by this method - return value
if (!val.__isDynamic) {
return val;
}
return dynamicFunc(val);
}
obj[prop] = () => dynamicFunc({});
obj[prop].__isDynamic = true;
return dynamicFunc(obj[prop]);
},
set(target, prop, value) {
// if our custom function was set to dynamic
if (typeof value === 'function') {
// wrap it to unwrap in get
target[prop] =
{
__isSetAsFunction: true,
func: value
};
}
else {
target[prop] = value;
}
return true;
},
apply: function (target, thisArg, argumentsList) {
return dynamicFunc({});
}
};
let proxy = new Proxy(input, handler);
return proxy;
};
return dynamicFunc(baseObj);我在这里使用代理类作为基本解决方案,所以用两个词--每次您试图访问某个属性时,它都会创建这个属性,如果它还不存在的话。它是不时编辑的,因为我堆积如山,需要解决这些问题,如下所示:)
样本:
let ob = dynamic();
ob.test1.test2.test3('hello from Belarus!','qwerty').test5.t('test');
//we could assign properties on the fly :
ob.myProp.pyProp2 = 2;
console.log(ob.myProp.pyProp2) // "1" will be outputed
// some tests using chai and chai-spies:
dynamic().genericProperties.anyFunc().myprop.test();
let obj = dynamic({ predefinedObjValue: 3 });
obj.prop1.prop2.test = 1;
obj.prop1.prop3.test = 2;
obj.prop2.myfunc = () => { };
expect(obj.prop1.prop2.test).to.be.equal(1);
expect(obj.prop1.prop3.test).to.be.equal(2);
expect(obj.predefinedObjValue).to.be.equal(3);
const myFuncSpy = chai.spy.on(obj.prop2, 'myfunc');
obj.prop2.myfunc();
expect(myFuncSpy).to.have.been.called();它也不会导致任何错误,您可以定义您自己的基本对象,并且它不会被覆盖:
let ob = dynamic({mycustomProp : 1});
ob.test1.test2.test3('asdasd','tt').test5.t('test'); //without error
console.log(ob.mycustomProp) // "1" will be outputed https://stackoverflow.com/questions/12150544
复制相似问题