1.prototype
我们可以简单的把prototype看做是一个模版,新创建的自定义对象都是这个模版(prototype)的一个拷贝 (实际上不是拷贝而是链接,只不过这种链接是不可见,给人们的感觉好像是拷贝)。
//'构造函数'a
function a(name){
this.name = name
} //原型属性,可共享
a.prototype.getName = function(){
return this.name;
} a.prototype.setName = function(name){
this.name = name;
return this.name;
} var b = new a('zqz'); //--内部实现
//看上去像copy 其实就是改变了实例的指针到a原型上
//复制'成员属性','成员函数'
var _b = {
getName:function(){
return this.name;
},
setName:function(name){
this.name = name;
return this.name;
}
} //还有构造函数的指向为a
var b = _b;
//--end //使用
b.getName() //=>zqz
b.setName('z') b.getName() //=>z ------------------- //把MyFn作为构造函数
function MyFn(){}
var a = new MyFn(); function MyFn(){}
var a = {}
MyFn.call(a) //将a对象作为this的指针调用MyFn函数
继承可以理解为一个对象从另一个对象获取属性的过程。
java:使用new创建对象时,会调用构造方法初始化对象。
constructor始终指向创建当前对象的构造函数
2.原型继承
左边跟右边都能实现方法的调用。
但是左边在每个实例对象的上创建一个个jiao对象副本。
而右边不会,因为不管new出多少对象。都只会共享原型上的一个jiao正本。prototype提供了一群同类对象共享属性和方法的机制。
function Person(name){
this.name = name;
} Person.prototype.Say = function(){
alert(this.name)
} function Emp(name, sal){
Person.call(this, name);
this.sal = sal;
} //这里的操作就是将Person这个类的方法跟属性复制一份出来给Emp的原型(原型上的Say是不会copy故去的,Say而是在Emp的原型链上)
//并且这时候Emp.prototype.constructor不再指向Emp这个构造函数,而是指向Person
//在原型模型中,为了实现类继承,必须首先将子类构造函数的prototype设置为一个父类的对象实例
Emp.prototype = new Person(); Emp.prototype.Show = function(){
alert(this.name + '$' +this.sal)
}
见图:
这里我们只是需要这个原型__proto__,而不需要name这类成员属性,因为这些对于继承来说没什么用。
3.多态性
对象可以覆盖原型对象的属性跟方法,但这钟覆盖其实是在自身对象上创建了新的属性和方法,只不过这些属性和方法与原型对象的同名而已。(原型上的其实并没有改变)
这中掩盖机制就是"多态"性。与静态语言的虚函数和重载不谋而合。
然后,更厉害的是,我们可以随之给原型对象动态添加新的属性和方法,从而动态的扩展基类的功能特性。
function Person(name){
this.name = name;
} Person.prototype.Say = function(){
alert(this.name)
} var xiaoming = new Person('小明')
xiaoming.Say() var xiaohong = new Person('小红'); //小红实现自己的Say方法,不会覆盖Person上的Say
xiaohong.Say = function(){
alert('我叫' + this.name)
}
xiaohong.Say();