5

明確にするために、DynamicObject(もちろんC#で)を継承するクラスは、動的であるJavaScriptの変数と同じ概念ではありません。DynamicObjectを使用すると、実装者は、メソッドを含め、オブジェクトが持つメンバーをプログラムで決定できます。

編集:JavaScriptオブジェクトには、実行時に任意のメンバーを追加できることを理解しています。それは私が話していることではまったくありません。DynamicObjectの機能を示すC#の例を次に示します。

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を生成します。戻り値は結果です。

4

4 に答える 4

2

Amazing the after only a few weeks of occasional JavaScript studies I've managed to find two answers:

ES6 Proxies

noSuchMethod

于 2012-09-16T15:37:55.353 に答える
1
于 2012-08-27T23:10:19.473 に答える
1

I stacked with similar question and wrote this code :

   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);

i use Proxy class as a base solution here, so in two words - every time you are trying to access some property it creates this property if it's not already there. it's time to time edited, because i stacked with issues and it's was need to solve them, so as is :)

Sample:

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();

and it will no cause any errors also, you can define your own base object and it will not be overrided :

let ob = dynamic({mycustomProp : 1});
ob.test1.test2.test3('asdasd','tt').test5.t('test'); //without error

console.log(ob.mycustomProp) // "1" will be outputed    

Working sample : https://codesandbox.io/s/cranky-liskov-myf65

于 2019-05-10T10:01:29.710 に答える
0

Edit 1: You can check the existence of a method by using typeof: If(typeof(obj.methodName)!= "undefined"){ //call methodName } If you want to specifically check for a function, its type will return "function". however, I don't know of any way to get the signature of the function, though JavaScript is fairly forgiving if your function handles nulls well.

Original answer I believe Ethan Brown had this right, in that all Javascript objects are basically just name-value pairs of variables, which are sometimes functions. Try the following code to alert a list of all properties and methods for any given object:

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));

Note that this is the same procedure used in How to list the properties of a JavaScript object by Slashnick

于 2012-08-27T23:16:25.990 に答える