原型的好处可以让所有对象实例共享它所包含的属性和方法。为了理解原型,需要先理解对象的概念
1. js中有两种对象,分别是函数对象和普通对象。
var fun1 = function(){}
console.log(typeof fun1); #function
var fun2 = new Function('myfunc','console.log(test);');
console.log(typeof fun2); #function
console.log(typeof Object); #function
console.log(typeof Function); #function
function f1(){}
var obj1 = new f1();
console.log(typeof obj1); #$object
var obj2 =new Object();
console.log(typeof obj2); #$object
var obj3 = new f1();
console.log(typeof obj3); #$object
在上面的例子中 obj1 obj2 obj3 为普通对象,func1 func2 为函数对象。怎么区分,其实很简单,凡是通过new Function()创建的对象都是函数对象,其他的都是普通对象。func1归根结底是通过 new Function()的方式进行创建的。Function Object 也都是通过 New Function()创建的。
2. 所有的函数对象都有prototype属性和
__proto__
属性,所有的普通对象都没有prototype属性,prototype属性指向的对象称为原型对象,
__proto__
用于指向创建它的函数对象的原型对象。在原型对象中有一个constructor属性,用来指向它的函数对象
var car = function(){
this.name = "i'm a car";
}
car.prototype.say = function()
{
return this.name;
}
var carObject = new car();
console.log(carObject.say());
上例中,car是一个函数对象,car的prototype属性指向它的原型对象,car的原型对象中有一个constructor属性指向car这个函数对象。carObject是car的一个实例,他有一个
__proto__
属性,此属性指向car的原型对象,同样的car的原型对象也有
__proto__
属性,指向创建它的函数对象Object的prototype,Object.prototype对象也有
__proto__
属性,但它比较特殊,为null,至此由car到null即构成了原型链
一般的原型对象是普通对象,但是Function的原型对象是函数对象,这是一个特例,虽然它是函数对象,但他没有prototype属性,
function f1(){};
console.log(f1.prototype) //f1{}
console.log(typeof f1. prototype) //Object
console.log(typeof Function.prototype) // Function,这个特殊
console.log(typeof Object.prototype) // Object
console.log(typeof Function.prototype.prototype) //undefined
从这句console.log(f1.prototype) //f1 {} 的输出就结果可以看出,f1.prototype就是f1的一个实例对象。就是在f1创建的时候,创建了一个它的实例对象并赋值给它的prototype,基本过程如下:
var temp = new f1();
f1. prototype = temp;
所以,Function.prototype为什么是函数对象就迎刃而解了,上文提到凡是new Function ()产生的对象都是函数对象,所以temp1是函数对象。
var temp1 = new Function ();
Function.prototype = temp1;
4.js中常用的继承方式:组合继承
function Box(name) {
this.name = name;
this.arr = ['哥哥','妹妹','父母'];
}
Box.prototype.run = function () {
return this.name;
};
function Desk(name, age) {
Box.call(this, name); //第二次调用Box
this.age = age;
}
Desk.prototype = new Box(); //第一次调用Box