将C#类转换为JavaScript

6

看看这个基础类:

namespace AcmeWeb
{
    public string FirstName { get; set; }

    public class Person 
    {
        public Person(string firstName, string lastName) 
        {
            if (String.IsNullOrEmpty(firstName))
            {
                throw new ArgumentNullException(firstName);
            }

            this.FirstName = firstName;
        }
    }
}

这段内容需要翻译成JavaScript语言,以下是我认为最佳的翻译方式:

我的思路如下:

(function(namespace) {

    namespace.Person = function(firstName, lastName) {

        // Constructor

        (function() {
            if (!firstName) {
                throw "'firstName' argument cannot be null or empty";
            }
        })();

        // Private memberts

        var _ = {
            firstName: firstName
        };

        // Public members

        this.firstName = function(value) {
            if (typeof(value) === "undefined") {
                return _.firstName;
            }
            else {
                _.firstName = value;
                return this;
            }
        };

    };

})(AcmeWeb);

2
首先,为什么要将它转换为JS?如果是因为您需要在客户端上使用该对象,您可以将您的类解析为JSON并将其传递给客户端,然后您就可以在客户端上像在服务器上一样处理JSON对象。 - Gary L Cox Jr
我只是在探索如何将JavaScript更加面向对象。 - AgileMeansDoAsLittleAsPossible
1
有一个叫做Script#的东西,它是将C#编译成JavaScript的编译器:http://projects.nikhilk.net/ScriptSharp。我从未尝试过这个,但这个想法听起来很不错。 - Uwe Keim
3个回答

3
您可以在JavaScript中使用真正的getter/setter。有关更多信息,请参见John Resig的帖子请查看这个例子
(function(NS) {
    NS.Person = function(firstName, lastName) {
        if (!firstName) {
            throw "'firstName' argument cannot be null or empty";
        }

        var FirstName = firstName;
        this.__defineGetter__("FirstName", function(){
            console.log('FirstName getter says ' + FirstName);
            return FirstName;
        });

        this.__defineSetter__("FirstName", function(val){
            console.log('FirstName setter says ' + val);
            FirstName = val;
        });
    }
})(AcmeWeb);

var p = new AcmeWeb.Person('John', 'Smith');
p.FirstName;          // => FirstName getter says John
p.FirstName = 'Joe';  // => FirstName setter says Joe

@Kirk Woll - http://jsfiddle.net/jruddell/xhB7E/。我只在Chrome中测试过这个。 - Josiah Ruddell

2
var AcmeWeb = {
    Person: function(firstName, lastName) {
        if (!firstName) {
            throw "'firstName' argument cannot be null or empty";
        }
        this.FirstName = firstName;
    }
};

然后,您可以创建一个新的Person对象:
var person = new AcmeWeb.Person("john", "smith");

我喜欢这个答案,因为在JS代码中,访问器/修改器除了让你必须调用person.firstname()之外,真的有什么作用呢? - Josiah Ruddell

2

它应该是这样的

(function(namespace) {
    namespace.Person = function(firstName, lastName) {
        var firstName    = firstName || 'default',
            lastName     = lastName || 'default',
            moarPrivates = 'foo';

        return {
            firstname: function(value) {
                if( value ) {
                    firstName = value;
                    return this;
                }
                else {
                    return firstName;
                }
            },
            lastname: function(value) {
                if( value ) {
                    lastName = value;
                    return this;
                }
                else {
                    return lastName;
                }
            }
        };
    };
}(AcmeWeb));

var Andy = AcmeWeb.Person('Andy', 'Foo');

Andy.firstname('Andreas').lastname('Baaaaar');
console.log('Hello, my name is ', Andy.firstname(), ' ', Andy.lastname());

通过返回对象字面量,构造函数中的所有局部变量都被闭合了。这就是它们为什么是私有的,只能从Person对象内部访问。公共方法是那些被封装到返回的对象字面量中的方法。
例如:http://www.jsfiddle.net/GkFu4/1/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接