详细

JavaScript _proto_、prototype原型、原型链、constructor构造器、类式继承、原型继承


1. prototype、proto、constructor、原型链

var Person = function(name)
{
this.name = name ;
};
var p = new Person("reamd");
console.log('参考下面的图示看效果更佳')
console.log('1 ', Person.__proto__ === Function.prototype); //true
console.log('2 ', Object.__proto__ === Function.prototype); // true
console.log('3 ', Function.__proto__ === Function.prototype); //true
console.log('4 ' + typeof p.__proto__); //objcect
console.log('5 ' + typeof Object.__proto__)//function
console.log('6 ', p.__proto__.__proto__ === Object.prototype); //true
console.log('7 ', Function.prototype.__proto__ === Object.prototype); //true
console.log('8 ' + Object.prototype.__proto__); //null
console.log('9 ', p.__proto__ === Person.prototype)//true
console.log('10 ' + p.constructor)//function(name)
console.log('11 ' + Person.constructor) //Functiion()
console.log('12 ' + Function.constructor)//Functiion()
console.log('13 ' + Object.constructor) //Functiion()
console.log('14 ' + p.__proto__.constructor)//function(name)
console.log('15 ' + Person.prototype.constructor) //function(name)
console.log('16 ' + Function.prototype.constructor) //Function()
console.log('17 ' + Object.prototype.constructor) //Object()

图示,上面的函数可用如下图例表示 prototype和_proto_的关系 知识点:

  1. 任何一个由构造器产生的对象都有_proto_属性,且此属性指向该构造器的prototype。
  2. 所有构造器/函数的_proto_都指向Function的prototype。
  3. Js中一切皆为对象
  4. proto 最终指向的都是Object.prototype
  5. constructor 指向创建当前对象的构造函数
  6. 函数.prototype.construnctor 指向这个函数(或函数A.prototype.construnctor 指向函数A)

*注: ①A.proto 指向 A的构造器.prototype (知识点1) ②A.constructor 指向 A的构造器 (知识点5) ③A.prototype.constructor 指向A (知识点6) *

总结

  1. A.constructor === A的构造器(A的构造函数)
  2. A._proto_ === A的构造器.prototype
  3. A.prototype === A的原型(原型对象)
  4. _proto_最终的指向都是Object.prototype._proto_为null,由此形成的链叫做原型链

2. 类式继承、原型继承

2-1 类式继承

//Super class
function Person(){
this.sex = 'man';
this.name='reamd';
this.age=23;
this.getName = function(){
return this.name;
};
};
Person.prototype.getAge = function(){
return this.age;
};
//sub class
function reader(){
reader.superclass.constructor.call(this);
};
//类式继承方法
function extend(sub,sup){
var f = function(){};
f.prototype = sup.prototype;
sub.prototype = new f();
sub.prototype.constructor = sub;
sub.superclass = sup.prototype;
if(sup.prototype.constructor !== sup)
sup.prototype.constructor = sup;
}
extend(reader,Person);
var r = new reader();
console.log(r.getName());
console.log(r.getAge());

2-2 原型继承

var Person = {
defaultName : 'zhangshengli',
getName : function(){
return this.defaultName;
}
};
var Reader = create(Person);
alert(Reader.defaultName);
//原型继承核心代码
function create(o) {
function F() {};
F.prototype = o;
return new F();
}

下面有两种变体

//第一种变体
Object.prototype.create= function () {
function F() {}
F.prototype = this;
return new F();
};
newObject = oldObject.create();
//第二种变体
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
newObject = Object.create(oldObject);