JS面向对象


以下是内容小点:

1. 使用funciton作为构造函数构建对象

2. 使用json作为构造函数的参数

3. 通过eval内置函数动态添加对象属性

4. 为对象新增方法

5. 使用JSON来创建对象

6. 使用Function作为对象创建,并把JSON属性赋予给Function

1. 使用function作为构造函数构建对象

对于类的创建来说,最常见的方法是提供一个构造函数来获取类的实例。


    <script type="text/javascript">   
        var Person = function(name, age, alias) {   
        this.name = name;   
        this.age = age;   
        this.alias = alias;   
         }   
           
        var person = new Person('leisure', 22);   
         alert('name: ' + person.name + ' age: ' + person.age);   
    </script>  

<script type="text/javascript"> var Person = function(name, age, alias) { this.name = name; this.age = age; this.alias = alias; } var person = new Person('leisure', 22); alert('name: ' + person.name + ' age: ' + person.age);</script>

示例1.

2. 使用json作为构造函数的参数

构造函数传参是一种非常平常的方式,但当有许多参数的时候,在创建时调用函数传参变得非常艰难,而且也较难阅读。除非该方法注有非常明确的注释,否则调用者必须仔细地数一下参数以及验证参数位置是否正确。而且javascript并没有重载这一特性(若两个函数同名,即只有最后声明的函数生效),所以也没法使用Java中的构造器重叠来解决。

JavaScript是可以把对象作为参数传递的。这样一来,JSON便是一个不错的选择。JSON是一个普通的数组,数组中的每个元素是由一个HashMap,HashMap分别存储键和值。所以说JSON是一个首选的传参对象。

JSON是一个以“{”开始,以“}”结束的对象,其内容是key: value,每个元素用“,”隔开,注意最后一个元素是不用添加“,”的。以下是一个简单的JSON对象:

var params = {name: 'leisure', age: 22};

示例片段1.

获取JSON属性的值是非常简单的,只需要通过 JSON对象 + "." + 键名即可获取键对应的值。

以下是示例2. ,相比于示例1. ,使用json作为参数传值更为灵活。


    <script type="text/javascript">   
        var Person = function(conf) {   
        this.name = conf.name;   
        this.age = conf.age;   
        this.alias = conf.alias;   
         }   
           
        var person = new Person({age: 22, name: 'leisure'});   
         alert('name: ' + person.name + ' age: ' + person.age);   
    </script>  

<script type="text/javascript"> var Person = function(conf) { this.name = conf.name; this.age = conf.age; this.alias = conf.alias; } var person = new Person({age: 22, name: 'leisure'}); alert('name: ' + person.name + ' age: ' + person.age);</script>

示例2.

3. 通过eval内置函数动态添加对象属性

this.name = conf.name;

this.age = conf.age;

this.alias = conf.alias;

要是参数有好几个,那么这样的语句要写好几行。

var name = 'leisure';

eval('alert(name);');

强大的eval把里面的语句变为JavaScript里的语句并执行。里面的name在eval里,也变成了外部name变量。其实就是相当于var name = 'leisure'; alert(name);对于示例2. ,我们也就可以使用eval('obj.' + key + '=conf[key]');这种形式就可以动态添加属性到对象了。以下是完整示例:


    <script type="text/javascript">   
        function apply(obj, conf) {   
            for(key in conf) {   
                 eval('obj.' + key + '=conf[key];');   
             }   
         }   
        var Person = function(conf) {   
             apply(this, conf);   
         }   
           
        var person = new Person({age: 22, name: 'leisure'});   
         alert('name: ' + person.name + ' age: ' + person.age);   
    </script>  

<script type="text/javascript"> function apply(obj, conf) { for(key in conf) { eval('obj.' + key + '=conf[key];'); } } var Person = function(conf) { apply(this, conf); } var person = new Person({age: 22, name: 'leisure'}); alert('name: ' + person.name + ' age: ' + person.age);</script>

示例3.

4. 为对象新增方法

在上述例子中

var person = new Person({age: 22, name: 'leisure', sayName: function() {alert('hi, my name is ' + this.name);}});

这样是允许的。

sayName在绝大部份人群都是共有的,所以我们希望写成

var person = new Person({age: 22, name: 'leisure'});

person.sayName();

var person2 = new Person({age: 23, name: 'jacky'}});

Person2.sayName();

而不是在每个实例中添加sayHello方法。

于是我们便天真地把方法写在构造函数里。希望实例能调用。

可不幸的是JavaScript不支持方法里面添加定义方法,只能是在方法里调用方法。以下便是一个错误的程序。


    <script type="text/javascript">   
        function apply(obj, conf) {   
            for(key in conf) {   
                 eval('obj.' + key + '=conf[key];');   
             }   
         }   
      
        var Person = function(conf) {   
         apply(this, conf);   
        function sayName() {   
        this.name;   
         }   
         }   
        var person = new Person({age: 22, name: 'leisure'});   
         alert('name: ' + person.name + ' age: ' + person.age);   
         person.sayName();   
    </script>  

<script type="text/javascript"> function apply(obj, conf) { for(key in conf) { eval('obj.' + key + '=conf[key];'); } } var Person = function(conf) { apply(this, conf); function sayName() { this.name; } } var person = new Person({age: 22, name: 'leisure'}); alert('name: ' + person.name + ' age: ' + person.age); person.sayName();</script>

示例4.

5. 使用JSON来创建对象

当我们绞尽脑汁怎样为一个对象添加公共的成员方法的时候,JSON这时再次出现在我们的脑海里。我们便可以改写成:


    <script type="text/javascript">   
        function apply(obj, conf) {   
        for(var key in conf) {   
         eval('obj.' + key + '=conf[key]');   
         }   
         }   
        var Person = {   
         company: 'pconline',   
         init: function(conf) {   
         apply(this, conf);   
        return this;   
         }   
         };   
           
        var person1 = Person.init({name: 'leisure', age: 22});   
        var person2 = Person.init({name: 'alex', age: 30, company: 'mycompany'});   
         alert('name: ' + person1.name + ' age: ' + person1.age + ' company:' + person1.company + '\n' + 'name: ' + person2.name + ' age: ' + person2.age + ' company:' + person2.company);   
    </script>  

<script type="text/javascript"> function apply(obj, conf) { for(var key in conf) { eval('obj.' + key + '=conf[key]'); } } var Person = { company: 'pconline', init: function(conf) { apply(this, conf); return this; } }; var person1 = Person.init({name: 'leisure', age: 22}); var person2 = Person.init({name: 'alex', age: 30, company: 'mycompany'}); alert('name: ' + person1.name + ' age: ' + person1.age + ' company:' + person1.company + '\n' + 'name: ' + person2.name + ' age: ' + person2.age + ' company:' + person2.company);</script>

示例5.

但是这时却出现了一个问题

person1和person2都同指一个内存

弹出的结果为


从结果看以看出person2覆盖了person1的属性,即使在创建时加上new,结果也一样。

var person1 = new Person.init({name: 'leisure', age: 22});

var person2 = new Person.init({name: 'alex', age: 30, company: 'mycompany'});

6. 使用Function作为对象创建,并把JSON属性赋予给Function

Js代码

    <script type="text/javascript">   
        function apply(obj, conf) {   
            for(key in conf) {   
                 eval("obj." + key + "=conf[key]");   
             }   
         }   
        var person = {   
             company: 'supercompany',   
             init: function(conf) {   
                 apply(this, conf);   
             }   
         };   
           
        var Person = new Function();   
         Person.prototype = person;   
           
        var person1 = new Person();   
         person1.init({name: 'leisure', age: 22});   
        var person2 = new Person();   
         person2.init({name: 'alex', age: 30, company: 'mycompany'});   
         alert('name: ' + person1.name + ' age: ' + person1.age + ' company:' + person1.company + '\n' + 'name: ' + person2.name + ' age: ' + person2.age + ' company:' + person2.company);   
    </script>  

<script type="text/javascript"> function apply(obj, conf) { for(key in conf) { eval("obj." + key + "=conf[key]"); } } var person = { company: 'supercompany', init: function(conf) { apply(this, conf); } }; var Person = new Function(); Person.prototype = person; var person1 = new Person(); person1.init({name: 'leisure', age: 22}); var person2 = new Person(); person2.init({name: 'alex', age: 30, company: 'mycompany'}); alert('name: ' + person1.name + ' age: ' + person1.age + ' company:' + person1.company + '\n' + 'name: ' + person2.name + ' age: ' + person2.age + ' company:' + person2.company);</script>

示例6.

弹出结果是


引用function apply(obj, conf) {
        for(key in conf) {
            eval(&quot;obj.&quot; + key + &quot;=conf[key]&quot;);
        }
}


貌似这么写看上去更清楚:

    function apply(obj, conf) {     
            for(key in conf) {   
                 obj[key] = conf[key];   
             }     
    }  

function apply(obj, conf) { for(key in conf) { obj[key] = conf[key]; } }



个人建议eval尽量减少甚至避免使用,一则性能低,二则难以做代码优化。

posted @ 2013-05-15 15:36  mguo  阅读(220)  评论(0编辑  收藏  举报