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("obj." + key + "=conf[key]");
}
}
貌似这么写看上去更清楚:
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尽量减少甚至避免使用,一则性能低,二则难以做代码优化。