原型、原型链、继承的使用

Javascript语言的继承机制一直很难被人理解。

它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain)模式,来实现继承。

Brendan Eich设计javascript之初是为了实现网页与浏览器之间交互的一种简单的脚本语言

如果真的是一种简易的脚本语言,其实不需要有"继承"机制。但是,Javascript里面都是对象,必须有一种机制,将所有对象联系起来。所以,Brendan Eich最后还是设计了"继承"。

实例对象中有__proto__,是对象,叫原型,不是标准的属性,浏览器使用,并且有的游览器不支持
构造函数中有prototype属性,也是对象,叫原型

注意 原型中的方法是可以互相访问的

我们先用一个构造器来实现一个构造函数:

function A(){
this.mark = “A”;
this.changeMark = function(){
this.mark += “_changed”;
}
}

A.prototype.mark2 = “A2”;
A.prototype.changeMark2 = function(){
this.mark2 += “_changed”;
}

var a = new A();
var a2 = new A();

//下面则说明构造函数实例化后,分配着不同的实例对象,互不相关
console.log(a.mark); //“A”
console.log(a2.mark); //“A”
a.changeMark(); //使用实例对象中的方法
console.log(a.mark); //“A_changed”
console.log(a2.mark); //“A”

//下面则说明了new操作符的一项作用,即将原型中的this指向当前对象,
//在a.changeMark2执行时,changMark2中的方法先找 this.mark2 的值,
//但是实例对象this中没有mark2值,则在原型链(后面会介绍)向上寻找,得到A原型对象中的mark2值,
//在赋值时,将修改后的值添加在了a实例中。
//总:虽然调用的是prototype方法,但是不会对prototype属性做修改,只会说是在实例中新增属性,但是在使用时,会最使用最近得到的属性(在后面原型链中可以加以理解)
console.log(a.mark2); //“A2”
console.log(a2.mark2); //“A2”
a.changeMark2(); //使用原型链中的方法
console.log(a.mark2); //“A2_changed”
console.log(a2.mark2); //“A2”

为什么a可以使原型中的changeMark2方法?这就和js巧妙的原型链相关,在Firefox中我们可以打印出对象并可查看到对象下面的__proto__。

我们把上面的过程用流程图来表示:

在这里插入图片描述

只有构造函数才会有prototype属性,而实例化出来的对象会拥有__proto__,而不会有prototype。

就像上图画的那样,两个实例化的对象都通过__proto__属性指向了A.prototype(即构造函数的原型对象)

而原型对象的__proto__指向Object对象,就像a.toString()的toString方法就是存在于Object原型对象(Object.prototype)中。

so:当使用对象的方法或属性时,对象会在一步一步通过__proto__向上寻找,找到最近的则是最终的获取到的方法或属性。

————这就是js中的原型链。

就像图上看到的一样,所有对象的原型链最终都指向了Object对象,而Object的原型对象(Object.prototype)是为数不多的不继承自任何属性的对象,即Object.prototype没有__proto__,是原型链的顶峰。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值