首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript等价于C#的DynamicObject?

JavaScript等价于C#的DynamicObject?
EN

Stack Overflow用户
提问于 2012-08-27 22:34:50
回答 4查看 573关注 0票数 5

首先要说明的是,继承DynamicObject的类(当然是在C#中)与JavaScript的变量是动态的不同。DynamicObject允许实现者以编程方式确定对象有哪些成员,包括方法。

编辑:我知道JavaScript对象可以在运行时向它们添加任何成员。我说的完全不是这个。下面是一个C#示例,展示了DynamicObject的功能:

代码语言:javascript
复制
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中创建一个对象,当函数调用语法在其上使用时,如下所示:

代码语言:javascript
复制
myAPI.uploadSomeData(data1, data2)

uploadSomeData调用转到类似于"TryGetMember“的函数,该函数使用名称"uploadSomeData”来执行$.ajax调用,结果是返回值。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-16 15:37:55

令人惊讶的是,经过几周的偶尔的JavaScript研究,我终于找到了两个答案:

ES6代理

noSuchMethod

票数 2
EN

Stack Overflow用户

发布于 2012-08-27 23:10:19

JavaScript允许在for...in循环中迭代对象的属性和方法。您可以确定它是否是使用typeof运算符的方法。

HTML:

<ul id="console"></ul>​

JavaScript:

代码语言: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中的某种元编程来构建智能和灵活的系统。

票数 1
EN

Stack Overflow用户

发布于 2019-05-10 10:01:29

我堆叠了类似的问题,并编写了以下代码:

代码语言:javascript
复制
   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);

我在这里使用代理类作为基本解决方案,所以用两个词--每次您试图访问某个属性时,它都会创建这个属性,如果它还不存在的话。它是不时编辑的,因为我堆积如山,需要解决这些问题,如下所示:)

样本:

代码语言:javascript
复制
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();

它也不会导致任何错误,您可以定义您自己的基本对象,并且它不会被覆盖:

代码语言:javascript
复制
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://codesandbox.io/s/cranky-liskov-myf65

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12150544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档