1、实现示例:
function Person(name, sex) {
this.name = name;
this.sex = sex;
}
Person.prototype = {
name:'无名氏',
sex:'未知',
nation:'火星',
getName: function() {
return this.name;
},
getSex: function() {
return this.sex;
},
getNation: function() {
return this.nation;
}
}
var people = new Person("Tom", "man");
alert(people.getName()); //使用构造对象时的name值
alert(people.getNation()); //使用原型中的nation值
我们把函数Person(也就是创建自定义对象的函数)称为构造函数,Person.prototype称之为Person的原型,可以看出JavaScript通过构造函数和原型的方式模拟实现了类的功能。prototype本质上是一个JavaScript对象,并且每个函数都有一个默认的prototype属性。prototype原型中的属性可以被原型所属的类的自定义对象引用。
如果将People理解为父类,要定义一个子类Employee继承父类原型中的属性。那么:
function Employee(employeeID,name,sex){
this.employeeID = employeeID;
this.name = name;
this.sex = sex;
}
Employee.prototype = new Person(); //将Employee的原型指向父类的对象
Employee.prototype.getEmployeeID = function() {
return this.employeeID;
};
//此时Employee的对象就可以调用Person中的方法
var boss = new Employee("001", "Jim", "man");
alert(boss.getEmployeeID()); //使用构造对象时的employeeID值
alert(boss.getName()); //使用构造对象时的name值
alert(boss.getNation()); //使用原型中的nation值
2、变量this:表示当前对象。如果在全局作用域内使用this,则返回当前页面对象window。如果在函数(方法)中使用this,则返回调用该函数的对象。可以使用call或apply重新指定this所代表的对象。
①在全局作用域内:
<script type="text/javascript">
alert(this === window); // true
</script>
②在函数内:
var fruit = "apple"; //定义一个全局变量,等价于window.fruit = "apple";
function test() {
alert(this.fruit);
}
test(); //apple
③在方法内:
var obj = {
fruit: "orange",
test: function(){alert(this.fruit);}
};
obj.test(); // "orange"
3、对象的constructor属性:始终指向创建该对象的构造函数。
var a = new Array(1, 56, 34, 12);
alert(a.constructor===Array); //true
var b = [1, 56, 34, 12];
alert(b.constructor===Array); //true
var c = new Function();
alert(c.constructor===Function); //true
var d = function(){};
alert(d.constructor===Function); //true
var Foo = function(){};
var obj = new Foo();
alert(obj.constructor.constructor === Function); //true
function Person(name) {
this.name = name;
}
var p = new Person("Tom");
alert(p.constructor===Person); //true
如果修改Person的prototype,Person创建的对象的constructor依然为Person
function Person(name) {
this.name = name;
}
//修改Person的原型,而不是全部覆盖其原型
Person.prototype.getName = function() {
return this.name;
};
var p = new Person("Tom");
alert(p.constructor===Person); //true
但如果覆盖掉Person的prototype,Person创建的对象的constructor则变为Object
function Person(name) {
this.name = name;
}
//覆盖Person的原型
Person.prototype = {
getName: function(){
return this.name;
}
};
var p = new Person("Tom");
alert(p.constructor===Person); //false
alert(p.constructor===Object); //true
这是因为覆盖Person的prototype时实际做的操作是:
Person.prototype = new Object({
getName: function(){
return this.name;
}
});
所以对象的constructor指向的是Object而非Person,可以用以下方法修正这个错误:
Person.prototype.constructor=Person;
特殊地:构造函数的原型的constructor也始终指向构造函数本身。
alert(String.prototype.constructor===String); //true
alert(Array.prototype.constructor===Array); //true
alert(Date.prototype.constructor===Date); //true
alert(Number.prototype.constructor===Number); //true
alert(Object.prototype.constructor===Object); //true
function Person(name) {
this.name = name;
}
alert(Person.prototype.constructor==Person); //true
参考:Douglas Crockford《JavaScript语言精粹》
http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html