文章导航

JavaScript prototype 原型

2018-10-5 16:03| 作者: admin| 查看: 2025| 评论: 0|来自: 蚂蚁部落

JavaScript是面向对象的语言,那么继承自然是其重要特征之一。

与标准面向对象语言不同,JavaScript继承主要通过prototype原型实现。

ES2015新增class类,继承方式从表面上更加趋近于标准面向对象语言,但实质上还是利用原型实现。

关于class样式类可以参阅JavaScript class类一章节。

一.基本概念:

每一个函数都具有prototype属性。

此属性指向一个对象,我们称此对象为原型对象。

a:3:{s:3:\"pic\";s:43:\"portal/201810/05/160401qbzbc8sqe3vvv3s6.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

由打印效果可以看到,函数func具有prototype属性,此属性指向一个对象(原型对象)。

为了满足实际需求,原型对象可能需要自定义,代码实例如下:

[JavaScript] 纯文本查看 复制代码运行代码
function func(){
  this.webName="蚂蚁部落"
}
func.prototype.address="青岛市南区";
func.prototype.age=6;
console.log(func.prototype);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201810/05/160425eggggot5o0e5bggj.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

可以看到为原型对象添加了两个属性。

将函数作为构造函数创建的对象实例会继承此原型对象中的成员。

代码实例如下:

[JavaScript] 纯文本查看 复制代码运行代码
function func(webName){
  this.webName=webName;
}
func.prototype.address="青岛市南区";
func.prototype.age=6;
let one=new func("蚂蚁部落一");
let two=new func("蚂蚁部落二");
console.log(one.webName);
console.log(one.address);
console.log(one.age);
console.log("-------------");
console.log(two.webName);
console.log(two.address);
console.log(two.age);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201810/05/160459w2bl0g49b49q7262.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

由上图可见,对象实例one与tow都继承了原型对象中的成员。

前面已经明确了对象实例可以继承原型对象成员,再来分析一下具体是如何继承原型对象成员的。

图示如下:

a:3:{s:3:\"pic\";s:43:\"portal/201810/05/160514kglokkpg189gozr9.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

图示分析如下:

(1).func函数的prototype属性指向原型对象。

(2).prototype原型对象具有两个自定义属性address与age。

(3).one与two是func构造函数创建的两个对象实例。

(4).对象实例有内部属性[[Prototype]],它指向函数的原型对象,__proto__属性可以访问此内部属性。

总结如下:

(1).构造函数内定义的属性/方法,对象实例独立所有,也就是每一个实例都切切实实有一份。

(2).被继承的原型对象中属性/方法是共享的。

看如下代码实例:

[JavaScript] 纯文本查看 复制代码运行代码
function func(webName){
  this.webName=webName;
}
func.prototype.address="青岛市南区";
func.prototype.age=6;
let one=new func("蚂蚁部落一");
let two=new func("蚂蚁部落二");
console.log(one.age);
console.log("-------------");
console.log(two.age);
// 修改原型对象age属性值为8
func.prototype.age=8;
console.log("-------------");
//两个实例对象age属性值改变为8
console.log(one.age);
console.log("-------------");
console.log(two.age);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201810/05/160549rzreztuhoa866mal.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

正式由于原型对象是共享的,所以改变原型对象的age属性值,两个实例对象的age属性值也跟着改变。

[JavaScript] 纯文本查看 复制代码运行代码
function func(webName){
  this.webName=webName;
}
func.prototype.address="青岛市南区";
func.prototype.age=6;
let one=new func("蚂蚁部落一");
let two=new func("蚂蚁部落二");

// 重置原型对象
func.prototype={
  url:"http://www.softwhy.com"
}
// 打印结果
console.log(one.age);
console.log(one.url);
console.log("-------------");
console.log(two.age);
console.log(two.url);

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201810/05/160617dn652y9bby5n5bnu.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

上面代码是重置原型对象,也就是说最初的原型对象被替换。

但是为什么age属性依然存在,反而新原型对象的url属性却没有找到呢。这是因为在重置原型对象之前,对象实例one与two已经被创建,__proto__指向原来的原型对象,现在重置原型对象实质就是将prototype指向一个新的对象,但是并没有人拨动__proto__指针指向这个新的原型对象,所以依然指向原来的原型对象。

2

鲜花

握手

雷人

路过

鸡蛋

刚表态过的朋友 (2 人)

最新评论

返回顶部