与C#和#x27;什么是动态对象?

与C#和#x27;什么是动态对象?,c#,javascript,C#,Javascript,需要明确的是,继承DynamicObject的类(当然是C#)与JavaScript的动态变量的概念不同。DynamicObject允许实现者以编程方式确定对象具有哪些成员,包括方法 编辑:我知道JavaScript对象可以在运行时添加任何成员。这根本不是我要说的。下面是一个C#示例,显示DynamicObject的功能: public class SampleObject : DynamicObject { public override bool TryGetMember(GetMe

需要明确的是,继承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调用以生成URL,返回值就是结果。

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

HTML:

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:

      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对象并调用其不存在的属性。唯一的方法是创建一个特殊的功能,它将实现开关、立面、地图等——任何允许使流程更加动态的构造

      像这样的

      您可以改进此逻辑,并根据用户的操作、传入的数据等动态向
      应用程序添加其他属性和功能。因此,总体而言,您可以使用JavaScript中的某种元编程来构建智能灵活的系统。

      编辑1: 您可以使用typeof检查方法的存在性: If(typeof(obj.methodName)!=“未定义”){ //调用方法名 } 如果您想专门检查函数,其类型将返回“function”。然而,我不知道有什么方法可以获得函数的签名,尽管如果你的函数能够很好地处理空值,JavaScript是可以原谅的

      原始答案 我相信Ethan Brown是对的,因为所有Javascript对象基本上都是变量的名称-值对,有时是函数。请尝试以下代码以警告任何给定对象的所有属性和方法的列表:

      function obj(prop){
          this.prop = prop;
          this.setProp = function setProp(prop){this.prop = prop};
                                               }
              var myObj = new obj("something");
          myObj.setProp("anything else");
      var getKeys = function(obj){
          var keys = [];
         for(var key in obj){
            keys.push(key);
         }
         return keys;
      }
      alert(getKeys(myObj));
      

      请注意,这与Slashnick在《神奇》中使用的过程相同。在偶尔进行几周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);
      
      我在这里使用代理类作为基本解决方案,因此,简单地说,每次您尝试访问某个属性时,它都会创建该属性(如果该属性尚未存在)。这是一次又一次的编辑,因为我处理了很多问题,需要解决它们,所以:)

      示例:

      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    
      

      工作示例:

      除非我误解了您的问题,否则Javascript对象都是这样工作的。在任何时候,您都可以在任何Javascript对象上创建新的属性和函数。
      for(myobject中的var属性){console.log(property);}
      我有一些关于Javascript的相关问题,可能对您有所帮助。我想您正在寻找,这(不幸的)是一个实验性的API.code!!代码。向我们展示不起作用的代码。或者说:你试过什么?对不起,我已经尽了最大努力来澄清这个问题,以防你想再试一次。