一、基于原型的继承

JavaScript中的面向对象和平常语言(c++,java)的面向对象是有一些不同的,在Java或者c++中是基于class的,但是在Javascript中没有class关键字。

function Foo(){
        this.y = 1;
    }
    console.log(typeof Foo.prototype); // Object
    Foo.prototype.x=4;
    var obj3 = new Foo();
    console.log(obj3.x);   //4
    console.log(obj3.y);   //1

在这个上面我们创建了一个构造函数Foo我们输出了一下这个构造函数prototype属性(注意这里说的是属性不是原型),然后我们通过这个属性给Foo函数增加了一个成员变量x我们实例了一个Foo函数为obj3,这样obj3和Foo之间是通过原型链来链接的。看下面的这个图:

我们是在这个原型链上添加的x这个成员变量,因为obj3是实例化Foo来的所以每个实例化后的对象也都有一个成员变量y,而x则不是每个函数对象的成员变量,它是属于原型链上。在原型链上的好处是当构造函数生成的时候这个成员就已经存在了,不是每次实例化都生成一个,如果每次都生成的话会浪费性能,所以一般的成员都会定义在原型链上。

在这里补充一下prototype是什么,每一个函数都有一个prototype属性,他是对象的属性(值为Object)而不是这个对象的属性,Foo函数有一个prototype的对象属性,它的作用是在当使用 new Foo()去构造父的实例时,Foo.prototype属性会作为new(构造)出来的对象的原型。prototype和原型是两回事,prototype是函数对象上预设的对象属性,而原型通常是obj3对象上的原型,指向构造器的prototype属性看下图:

每个函数在定义的时候都会自动生成两个属性constructor__proto__,看下图就能明白:

二、原型链

什么是原型链?
,Javascript 只有一种结构,那就是:对象。在 javaScript 中,每个对象都有一个指向它的原型(prototype)对象的内部链接。这个原型对象又有自己的原型,直到某个对象的原型为 null 为止(也就是不再有原型指向),组成这条链的最后一环。这种一级一级的链结构就称为原型链(prototype chain).

先来看一段代码:

function person(name,age){
this.name=name;
this.age=age;
}
person.prototype.hi=function(){
console.log("Hi my name is"+this.name+"dddddddddddd");
};
person.prototype.legs=2;
person.prototype.arms=2;
person.prototype.walk=function(){
console.log(this.name+"is walking.....");
};
function student(name,age,className){
person.call(this,name,age);
this.className=className;
}
student.prototype.hi=function(){    //当继承之后子元素会覆盖父元素
    console.log("i am a student");
}
student.prototype=Object.create(person.prototype);
student.prototype.constructor=student;
var bosn=new student('bosn',27,'class 3,grade 2');
bosn.hi();
bosn.walk();

这段代码显示定义了person类然后用student继承person最后实例化了一个student类为bosn

这个原型链可以看下图:

来介绍一下这个图:实例化的bosn的原型指向student的原型person的原型指向object指向null当调用成员函数或者成员变量的时候是按照原型链向上查找的,如果找到了就返回,不想上查找了,如果原型链上没有就一直找到null为止。

:并不是所有的对象都有object.prototype比如下面这个

三、了解prototype

改变prototype

首先先来看一下代码:

student.prototype.x  =  121;
console.log(bosn.x);  //121
student.prototype =  {y:212};
console.log(bosn.x);//121
console.log(boxn.y);//undeifned

var helios = new student('1',2,'3');
console.log(helios.x); //undefined
console.log(helios.y);  //212

当已经实例化一个对象之后,他会按照实例化时候的原型链进行操作,实例化之后改变原型链上的属性并不会影响已经实例化完对象,在有一次实例化原型链之后才会受到影响

内置构造器的prototype

在JavaScript中每个内置对象,每个内置对象也是可以设置prototype的 。

Object.prototype.x=1;