使用构造函数虽然极大地方便了创建不同类的对象,但是有时候不同的对象需要共享一些数据和方法,这时候,我们就要用到原型了。
原型的创建
function Box(){}// 构造函数体内什么都没有,如果有,叫做实例方法和实例属性
Box.prototype.name = 'Lee';// 原型属性
Box.prototype.age = 100;// 原型属性
Box.prototype.run = function(){// 原型方法
return this.name + this.age +'运行中...';
}
原型属性与方法
var box1 = new Box();
var box2 = new Box();
document.write("box1对象输出:")
document.write("<br/>")
document.write(box1.age)
document.write("<br/>")
document.write(box1.name)
document.write("<br/>")
document.write(box1.run())
document.write("<br/>")
document.write("box2对象输出:")
document.write("<br/>")
document.write(box2.age)
document.write("<br/>")
document.write(box2.name)
document.write("<br/>")
document.write(box2.run())
document.write("<br/>")
document.write("box1、box2对象属性与方法的比较:")
document.write("<br/>")
document.write(box1.name == box2.name)
document.write("<br/>")
document.write(box1.age == box2.age)
document.write("<br/>")
document.write(box1.run() == box2.run())
document.write("<br/>")
document.write(box1.run == box2.run)
执行结果:
box1对象输出:
100
Lee
Lee100运行中...
box2对象输出:
100
Lee
Lee100运行中...
box1、box2对象属性与方法的比较:
true// name属性相等
true// age属性相等
true// run方法运行结果相等
true// run方法引用地址相等
通过运行结果,可以看到,两个对象的属性值和方法的运行结果都相等,甚至方法引用的地址也相等。这就体现了共享的思想。
就近访问原则
var box1 = new Box();
var box2 = new Box();
box1.name = "Jack";
document.write(box1.name);
document.write("<br/>")
document.write(box2.name);
输出结果:
Jack// box1.name
Lee// box2.name
可以看到box1.name = “Jack”;赋了新的值,但是box2.name的值并未改变,也就是原型属性name的值并未改变。
可见,我们这里的操作box1.name = “Jack”,是为box1添加了一个实例属性,输出的时候,输出的也是实例属性,这叫做就近原则。
var box1 = new Box();
box1.name = "Jack";// 实例属性,没有重写原型属性
document.write(box1.name);// 就近原则
document.write("<br/>")
delete box1.name;// 删除实例中的属性
document.write(box1.name);
输出结果:
Jack // 实例属性输出
Lee // 原型属性输出
删除实例属性之后,输出的属性值依然是原型属性的值。
判断是否存在指定属性
hasOwnProperty方法
var box1 = new Box();
document.write(box1.hasOwnProperty('name'));// 判断实例中是否存在指定属性
document.write("<br/>")
box1.name = "Jack";
document.write(box1.hasOwnProperty('name'));// 判断实例中是否存在指定属性
输出结果:
false
true
in操作符
var box1 = new Box();
document.write('name' in box1);// 实例或原型中存在该属性即返回true,实例或原型中都不存在该属性,返回false
判断原型中是否存在某个属性
var box1 = new Box();
function hasProperty(obj, property){
return !obj.hasOwnProperty(property) && (property in obj);
}
document.write(hasProperty(box1,'name'));
输出:
true
构造函数方式和原型方式的比较
以构造函数方式创建的两个实例在内存中是相互独立、互不影响的。
原型模式方式创建的实例中,自动生成了一个属性proto,该属性是实例指向原型对象的一个指针,它的作用就是指向构造函数的原型属性constructor。通过这两个属性就可以访问到原型里的属性和方法了。