浅谈JavaScript之原型
上一篇谈new关键字也是给这一篇写关于原型的文章买个伏笔,我对原型的理解可能会有偏差,如有错误,望指正一定修改,望各位道友如果想真正的理解原型的概念一定要再看完各方言论再回归教材。
言归正传谈原型,首先原型是一个对象,无论什么时候,只要创建了一个函数,就会按照规则创建一个Prototype属性,这个属性指向函数的原型对象,在默认情况下,所有的原型对象都会有一个constructor属性,这个属性又指向函数的原型对象。先来段代码
function Person(){} Person.prototype.name = "王方"; Person.prototype.age= 23; Person.prototype.job= "前端开发"; Person.prototype.sayName= function(){ alert(this.name) } var person1 = new Person(); person1.sayName(); //“王方” var person2 = new Person(); person2.sayName(); //“王方”
在上面的例子中,Person.prototype.constructor指向Person,通过这个构造函数,我们还可以继续为原型添加其他属性以及方法。解释原型,用例子远比用言语解释要好一些。
继续看
//创建一个函数b var b = function(){ var one; } //使用b创建一个对象实例c var c = new b(); //查看b 和c的构造函数 b.constructor; // function Function() { [native code]} b.constructor==Function.constructor; //true c.constructor; //实例c的构造函数 即 b function(){ var one; } c.constructor==b //true //b是一个函数,查看b的原型如下 b.constructor.prototype // function (){} b.__proto__ //function (){} //b是一个函数,由于javascript没有在构造函数constructor和函数function之间做区分,所以函数像constructor一样, //有一个原型属性,这和函数的原型(b.__proto__ 或者b.construtor.prototype)是不一样的 b.prototype //[object Object] 函数b的原型属性 b.prototype==b.constructor.prototype //fasle b.prototype==b.__proto__ //false b.__proto__==b.constructor.prototype //true //c是一个由b创建的对象实例,查看c的原型如下 c.constructor.prototype //[object Object] 这是对象的原型 c.__proto__ //[object Object] 这是对象的原型 c.constructor.prototype==b.constructor.prototype; //false c的原型和b的原型比较 c.constructor.prototype==b.prototype; //true c的原型和b的原型属性比较 //为函数b的原型属性添加一个属性max b.prototype.max = 3 //实例c也有了一个属性max c.max //3
上面的例子中,对象实例c的原型和函数的b的原型属性是一样的,如果改变b的原型属性,则对象实例c的原型也会改变。
prototype与__proto__
关于它们的区别,我就只在一方面来讲吧,如上面例子,给b的prototype添加属性值,实例对象也可以继承到,再给个例子
var A = function(name) { this.name = name; } var a = new A('alpha'); a.name; //'alpha' A.prototype.x = 23; a.x; //23
因为在a实际被创建之后,a.__proto__是一个对A.prototype 的一个引用。所以修改原型属性,就会有改变。
但是如果对A的原型进行修改,并不会反应到A所创建的实例a中,如下面的例子
var A = function(name) { this.name = name; } var a = new A('alpha'); a.name; //'alpha' A.prototype = {x:23}; a.x; //null
哈,说了这么多,原型到底能做什么呢?
原型的用途
因为每个对象和原型都有一个原型(注:原型也是一个对象),对象的原型指向对象的父,而父的原型又指向父的父,我们把这种通过原型层层连接起来的关系撑为原型链。
通过原型以及原型链,可以让所有的对象实例共享它所包含的属性和方法,就不必在构造函数中定义了。
限于笔者的水平有限,对于原型的介绍也比较粗糙,不足之处有很多,望各位道友指正。