JavaScript面向对象和继承机制
var school = new Object(); school.name = '珠峰培训'; school.teacher = '耿老师'; school.sayName = function() { alert(this.name); } school.sayName();
(2)对象字面量创建对象(单例模式):
var school = { name: '珠峰培训', teacher: '耿老师', sayName: function() { alert(this.name); } } school.sayName();
注意:虽然Object构造函数和对象字面量都可以创造单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量的重复代码。
(3)工厂模式:
function createSchool(name, teacher) { var o = new Object(); o.teaacher = teacher; o.name = name; o.sayName = function() { alert(this.name); } return o; } var school1 = createSchool('珠峰培训', '耿老师'); school1.sayName();
注意:工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。
(4)构造函数模式:
function School(name, teacher) { this.name = name; this.teacher = teacher; this.sayName = function() { alert(this.name); } } var school1 = new School(' 珠峰培训', '耿老师'); school1.sayName();
注意:使用构造函数的主要问题是每个方法都要在每个实例上重新创建一遍,所以上面sayName与下面代码是逻辑上等价的:
this.sayName = new Function('alert(this.name)');
因此,不同实例上的同名函数是不相等的:
function School(name, teacher) { this.name = name; this.teacher = teacher; this.sayName = function() { alert(this.name); } } var school1 = new School('珠峰培训', '耿老师'); var school2 = new School('珠峰培训', '耿老师'); alert(school1.sayName == school2.sayName); //输出结果fals
然后,创建两个完成相同任务的Function实例的确没有必要,如果把函数转移到构造函数外部,会解决此问题:
function School(name, teacher) { this.name = name; this.teacher = teacher; this.sayName = sayName; } function sayName() { alert(this.name); } var school = new School('珠峰培训', '耿老师'); school.sayName();
上面的修改虽然解决了多次实例化Funtion对象,但是全局函数过多的话就没有封装性可言了。
(5)原型模式:
我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是所有实例共享属性和方法:
function School() { School.prototype.name = '珠峰培训'; School.prototype.teacher = '耿老师'; School.prototype.sayName = function() { alert(this.name); } } var school1 = new School(); school1.sayName(); var school2 = new School(); school2.sayName(); alert(school1.sayName == school2.sayName); //输出结果true;
注意:school1.sayName===school2.sayName比较结果为true,因为指向内存中同一地址。 大多数情况下并不是所有属性方法都要共享,所以更多情况用构造函数和原型模式的组合方式。