1.prototype的定义
在JavaScript中,我们创建的每一个对象都有一个prototype属性,这个属性会返回对象类型原型的引用,所以它就能为一个特定的类声明通用的变量或函数。
prototype属性不需要显式声明,它在构造函数中已经存在:
function Test(){}
alert(Test.prototype); //Object
prototype是一个对象,所以我们就能给它添加属性,且这个属性会成为通用属性。
function Person(name,age,job){
this.name = name ;
this.age = age ;
this.job = job ;
}
Person.prototype.country = "China";
var person_one = new Person("Mike",21,"Student");
var person_two = new Person("Jack",34,"Engineer");
alert(person_one.country); //China
alert(person_two.country); //China
我们没有为person_one 和 person_two特别声明country属性,但是两人都拥有这个属性。这是因为当一个对象被创建的时候,构造函数会把它的属性prototype赋给新对象的内部属性__proto__,这个属性被对象用来查找它的属性。
2.给对象添加公共属性和方法
因为上面的特性,我们可以用prototype来给对象添加公共的属性和方法:
function Employee(name, salary){
this.name=name;
this.salary=salary;
}
Employee.prototype.getSalary=function getSalaryFunction(){
return this.salary;
}
Employee.prototype.addSalary=function addSalaryFunction(addition){
this.salary=this.salary+addition;
}
var boss1=new Employee("Joan", 180000);
var boss2=new Employee("Kim", 120000);
var boss3=new Employee("Sam", 150000);
alert(boss1.getSalary()); // 输出 180000
alert(boss2.getSalary()); // 输出 120000
alert(boss3.getSalary()); // 输出 150000
这样就实现了公共函数和属性。
而当原型和实例中存在相同的函数和属性时,调用它们会有什么效果呢?
function Person(){
this.number = 5;
}
Person.prototype.number = 10;
var person_one = new Person();
alert(person_one.number); //5
通过以上代码测试发现,调用的是实例中的属性和函数,原型中的属性和函数就会被屏蔽。
3.constructor属性
prototype对象中其实已经包含了两个属性,一个是constructor,另一个是__proto__
对象方法与通过new创建对象的有一个重要区别。这个区别就是function定义的方法(对象方法)有一个prototype属性,使用new生成的对象就没有这个prototype属性。也就是prototype属性是对象方法或者构造方法的专有属性。prototype属性又指向了一个prototype对象,注意prototype属性与prototype对象是两个不同的东西,要注意区别。在prototype对象中又有一个constructor属性,这个constructor属性同样指向一个constructor对象,而这个constructor对象恰恰就是这个function函数本身,即指回了对象。所以我们需要理解好prototype和constructor的关系。
总结:prototype属性在JavaScript中经常出现但是理解起来又比较复杂,需要多下点功夫。