与C#和#x27;什么是动态对象?
需要明确的是,继承DynamicObject的类(当然是C#)与JavaScript的动态变量的概念不同。DynamicObject允许实现者以编程方式确定对象具有哪些成员,包括方法 编辑:我知道JavaScript对象可以在运行时添加任何成员。这根本不是我要说的。下面是一个C#示例,显示DynamicObject的功能:与C#和#x27;什么是动态对象?,c#,javascript,C#,Javascript,需要明确的是,继承DynamicObject的类(当然是C#)与JavaScript的动态变量的概念不同。DynamicObject允许实现者以编程方式确定对象具有哪些成员,包括方法 编辑:我知道JavaScript对象可以在运行时添加任何成员。这根本不是我要说的。下面是一个C#示例,显示DynamicObject的功能: public class SampleObject : DynamicObject { public override bool TryGetMember(GetMe
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!!代码。向我们展示不起作用的代码。或者说:你试过什么?对不起,我已经尽了最大努力来澄清这个问题,以防你想再试一次。