您的位置:首页 > Web前端 > JavaScript

JavaScript面向对象笔记–原型

2016-09-17 20:37 399 查看
每个函数都有
prototype
属性,这个属性存储的就是原型对象。在基于原型的面对对象的方式中,对象(object)是依靠构造器(constructor)利用原型(prototype)构造出来的

当我们使用构造器函数创建一个对象的时候,该对象会自动创建一个__proto__的属性,该属性保存着指向构造器函数的原型对象的神秘链接,该原型对象实现了对象的属性或方法的共享。当然原型对象也是对象也会有构造器函数,那么原型对象里面也会有一个__proto__属性,用于指向原型对象的构造器函数的原型对象(有点绕,下面会有图示)

在 ECMAScript 中,每个由构造器创建的对象拥有一个指向构造器 prototype 属性值的 隐式引用(implicit reference),这个引用称之为 原型(prototype)。进一步,每个原型可以拥有指向自己原型的 隐式引用(即该原型的原型),如此下去,这就是所谓的 原型链(prototype chain) 。

原型中一般用来存储要继承的属性或方法,里面的内容共享出来,供实例使用。下面通过实例来理解

//构造函数
function Mother(name){
this.name =name; //实例属性name,不同的实例对象有不同的name属性
}
//定义Mother构造函数的原型,原型对象的属性和方法会被实例继承
Mother.prototype = {
age : 20,       //原型属性,不是单个实例对象仅有的,每个对象都会有
hello:function(){ //原型方法
console.log("hello,"+this.name);
}
}
//使用构造器函数,定义两个实例对象
var son = new Mother("son");
var girl = new Mother("girl");


我们在Google developer tools中查看

我们看到son和girl实例对象中都有属性name,但属性值不一样,都有继承于原型的age属性(son.age在这里寻找的过程是,先在son对象中找,找不到,OK,去son.__proto__也就是son对象的构造函数的原型中寻找age属性,OK找到了返回–要是在构造器函数的原型对象中还是没有找到,那行,接着往构造器函数的原型对象的构造器函数的原型对象中去找,这样一层一层找,直到Object对象,Object对象的原型对象的__proto__为null)和hello方法,不同对象调用方法,打印出不同的提示信息,下面我们看看他们之间的关系是怎么样的





首先我们看__proto__,这个是实例对象指向构造函数原型的一个神秘链接,我们应该知道javascript中除了基本5种基本的数据类型外,其他的值都可以看做是一个对象,那么每个对象都会有__proto__属性,正如上面这张图中的,我们在工具中查看



通过实例我们可以验证

对象的__proto__属性指向的就是对象构造函数的原型对象

但是这里会有一个问题



我们在打印son.constructor OR girl.constructor的时候会发现指向的构造函数不是
Mother()
,而是
Object()
,这是为什么呢?

Mother.prototype = {
age : 20,       //使用的是字面量的方式定义原型
hello:function(){
console.log("hello,"+this.name);
}
}


为了更好的体现封装的效果我们使用的
字面量
定义方式,这样会产生上面的问题,

son.constructor OR girl.constructor的时候会发现指向的构造函数不再是Mother(),而是Object(),

产生的原因是Mother.prototype ={},这种写法创建了一个新的对象,调用了Object()这个函数,新创建的对象的constructor就指向了Object(),并且重写了原来的Mother原型的constructor,导致我们这个问题,

一般解决办法

我们可以在字面量中声明属性
constructor:Mother
,强制指定



我们看到强制指定后constructor指向的函数达到我们的预期
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript prototype
相关文章推荐