《JavaScript高级程序设计 第三版》学习笔记 (五) 继承详解

  面向对象语言有两种继承方式:接口继承(只继承方法名);实现继承(继承实际的方法)。但在ECMAScript中,函数名没多大含义,只是函数体的引用而已,因此,ECMAScript无法实现接口继承,只支持实现继承。实现继承,主要是依靠原型链来完成的。

一、原型链

1.原型链的基本思想是:利用原型让一个引用类型继承另一个引用类型的属性和方法。
2.构造函数、原型、实例之间的关系
(1)每个构造函数都有一个原型对象,Func.prototype指向了这个原型对象。
(2)原型对象都包含一个指向构造函数的指针,Func.prototype.constructor等于Func,可以理解为prototype和constructor是两个方向相反的指针,在构造函数和原型之间搭建起桥梁。
(3)每个实例,都包含一个指向原型对象的内部指针__proto__,当然这个对开发人员是不可见的。
(4)如果把构造函数A的原型,设成构造函数B的一个实例,那么构造函数A的原型里就包含了指向另一个原型的指针,从而形成了原型链。这样就实现了继承。使用对象的属性或方法时,解析器先搜索实例内部,找不到就搜索实例的原型内部,再找不到就搜索实例的原型的构造函数的原型内部,一级一级向上查找。
//小实验
function Human(){

}
Human.prototype.getSex=function(){return this.sex;}
Human.prototype.setSex=function(v){this.sex=v;}

function Male(){
	this.setSex("male");
}
Male.prototype=new Human();
Male.prototype.getAge=function(){return this.age;}
Male.prototype.setAge=function(v){this.age=v;}


var tom=new Male();
tom.setAge(20);

alert(tom.getSex());//male
alert(tom.getAge());//20
alert(tom instanceof Male);//true
alert(tom instanceof Human);//true
alert(tom instanceof Object);//true
alert(tom.constructor == Male);//false
alert(tom.constructor == Human);//true
(5)原型链的最顶端是Object,这就是为什么所有引用类型instanceof Object都会返回true。换句话说,只要instanceof后面的构造函数在实例的原型链中,都会返回true。
(6)注意,由于继承的时候,原型被重写了,所以tom的constructor指像的不再是Male,而是Male.prototype的构造函数Human。
3.使用原型链做继承的问题。
(1)和原型模式创建对象一样,使用原型链做继承,也会遇到多个实例共享object(引用类型)属性的情况。这也就是为啥引用类型属性要放在构造函数内部。
(2)更严重一个问题是,使用原型链做继承时,必须用基类的实例去替换派生类的原型,产生基类的实例的过程是不能使用参数的,这就大大降低了继承的灵活性。

二、借用构造函数

1.为了解决原型链做继承遇到的第一个问题,出现了借用构造函数的方法。思想是把基类的构造函数当作普通函数执行一次,但执行的时候,必须把派生类的执行空间传过去。
//小实验
function Human(){
	this.sex="Please input";
	this.age=-1;	
}

function Male(){
	Human.call(this);//显示地把基类构造函数当作普通函数调用。
}
Male.prototype=new Human();

var tom=new Male();
var jim=new Male();
tom.sex="male";
alert(tom.sex);//male
alert(jim.sex);//Please input
2.当然,构造时不传递参数用处还是不大,幸好apply和call都是支持传参的。
//小实验
function Human(sex,age){
	this.sex=sex;
	this.age=age;	
}

function Male(age){
	Human.apply(this,["male",age]);
}
Male.prototype=new Human();

var tom=new Male(30);
var jim=new Male(25);
alert(tom.sex);//male
alert(jim.age);//25
alert(tom.age);//30
3.借用构造函数解决了引用类型属性的问题,但没有解决方法的问题。

三、组合继承(伪经典继承)

1.这种继承是把原型链和借用构造函数结合起来。用借用构造函数处理属性,用原型链处理方法。其实就相当于创建对象时提到的“组合模式”
//小实验
function Human(sex){
	this._sex=sex;
}
Human.prototype.getSex=function(){return this._sex;}
Human.prototype.setSex=function(v){this._sex=v;}

function Male(name,age){
	Human.call(this,"male");
	this.name=name;
	this.age=age;
}
Male.prototype=new Human();
Male.prototype.sayHello=function(){
	alert("Hello, my name is "+this.name+", I'm "+this.age+" years old, I'm a "+(this.getSex()=="male"?"boy":"girl")+".");	
}

var tom=new Male("tom",15);
var jan=new Male("jan",13);
jan.setSex("female");
tom.sayHello();
jan.sayHello();
2.这是目前最常用,也是解决最完美的继承写法了,没有之一。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript高级程序设计(第3版)》是一本权威的JavaScript编程指南,涵盖了JavaScript语言的各个方面和高级特性。本书由Nicholas C. Zakas撰写,是一位知名的JavaScript专家和作者。 该书详细介绍了JavaScript的基本语法、数据类型、控制流程等基础知识,并深入探讨了函数、对象、正则表达式等高级特性。此外,本书还介绍了DOM操作、事件处理、Ajax、JSON等Web开发相关的内容。读者可以通过学习本书,系统地掌握JavaScript的各个方面,从而能够编写出可维护、高效、优雅的JavaScript代码。 《JavaScript高级程序设计(第3版)》以清晰、易懂的语言讲解了复杂的概念,并配有丰富的示例代码和实际案例,帮助读者理解和应用所学知识。本书不仅适合初学者,也适合有一定JavaScript基础的开发者作为参考手册使用。 随着Web技术的快速发展,JavaScript已经成为构建现代Web应用的重要工具之一。《JavaScript高级程序设计(第3版)》为读者提供了全面、深入的学习和理解JavaScript的资源。无论是对于Web开发者还是对于想要了解JavaScript的任何人来说,这本书都是一本不可或缺的经典之作。 总之,《JavaScript高级程序设计(第3版)》是一本内容丰富、权威性强的JavaScript编程指南,它深入讲解了JavaScript的各个方面和高级特性,对于理解和应用JavaScript具有很高的参考价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值