跟着博客园和CSDN上的各位前辈学习啦
Javascript中的对象就是一个指向prototype 的指针 和一个自身属性的列表。javascript创建对象时采用了写时复制的理念。只有构造器才具有prototype属性,原型链继承就是创建一个新的指针,指向构造器的prototype属性。javascript中的每一个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。
构造器包括:
1.Object
2.Function
3.Array
4.Date
5.String
函数也是一种对象,它也是属性的集合,我们也可以对函数进行自定义属性。每个构造函数内部均有一个prototype原型指针,指向该类型的原型对象C.prototype。原型对象C.prototype中包含一个回指向构造函数的指针constructor。这样就实现了构造函数和原型对象之间的双向绑定。每个实例对象内部也包含一个指向原型对象C.prototype的指针。
如下图:SuperType是一个函数,右侧是它的原型
原型既然是一个对象,属性的集合,不仅仅只有constructor这一个属性,可以自定义增加很多属性。例如:
举例:
function Person(name){
this.name = name
};
Person.prototype.getName = function(){
return this.name;
};
var p = new Person("zhangsan");
console.log(Person.prototype.constructor);//输出 f Person(name){this.name = name}
console.log(p.constructor);//输出 f Person(name){this.name = name}p本身不包含constructor属性,所以这里其实调用的是Person.prototype.constructor
再看下面的代码:
function Person(name){
this.name = name
};
Person.prototype.getName = function(){
return this.name;
};
var p = new Person("zhangsan");
function Animal(){}
Animal.prototype.name = "xiaoming";
console.log(Animal.prototype);//输出{name:"xiaoming",constructoor:f}
Person.prototype = new Animal();//修改了prototype的指向,让Person 能获取Animal中的Prototype属性中的方法
// Person.prototype = Animal.prototype;
var p2 = new Person("zhang san");
console.log(p2.constructor);//输出f Animal(),其实p2.constructor其实就是Animal.prototype.constructor,但是为了证实p2是Person的实例,这里应该输出f Person()
代码本来要达到的目的是:
1. 表明Person 继承Animal
2. 表明p2是Person 的实例
此时为了实现目的2,可以修改Person函数对象prototype属性中constructor的指向
Person.prototype = new Animal();
Person.prototype.constructor = Person;
此时,p2.constructor确实是指向了Person这个函数,表示p2是Person类的实例,但是新问题出现了,目的2实现了,但是目的1却没达到,此时prototype表达了矛盾的两个意思:
1.表示自己的父类是谁
2.作为自己的实例原型来复制
因此我们不能直接用prototype属性表示父类是谁,而是用getPrototypeof()方法来知道父类是谁
实例:
Person.prototype = new Animal();
Person.prototype.constructor = Person;
var p2 = new Person("ZhangSan");
p2.constructor //显示 function Person() {}
Object.getPrototypeOf(Person.prototype).constructor //显示 function Animal() {}
当代码p = new Person()执行的时候,new做了如下几件事情
- 创建了一个空白对象
- 创建了一个指向Person.prototype的指针
- 将这个对象通过this关键字传递到构造函数中去,并执行构造函数
function Person(name){
this.name = name;
};
Person.prototype.getName = function(){
return this.name;
};
var person();//其实就类似于
//var person = new Object();
//person.getName = Person.prototype.getName;
因此通过person.getName()调用方法时,this指向的是这个新创建的对象,而不是prototype对象