JavaScript学习笔记(三)—— 继承的实现

一、JavaScript实现继承的三层含义:

 

① 子类的实例可以共享父类的方法;

② 子类可以覆盖父类的方法或者扩展新的方法;

③ 子类和父类都是子类的实例。


二、实现继承的几种方法:

1、原型链继承

例:function Box( ){           //被继承的函数叫超(父)类型;

this.name = “Andy”;

}

function Desk( ){           //继承的函数叫子类型

this.age = 25;

}

Desk.prototype = new Box( );   //将Box构造里的信息和原型信息都给Desk

var desk = new Desk( );

alert(desk.name);    //返回 Andy;

Desk.prototype.name = "Jack”; //重写父类型中的属性

var desk2 = new Desk();

alert(desk2.name);   //返回 Jack;

ps:  ① 如上例,若子类型要重写父类型中某个方法或属性,给原型添加的代码一定要放在替换原型的语句之后。

② 在通过原型链继承时,不能使用字面量创建原型对象,这样会重写原型链


2、对象冒充法(即 借用构造函数)

解决引用共享和超类型无法传参的问题,采用“对象冒充”技术继承。

例:function Box (name,age){

this.name  = “Andy”;

this.age = 25;

this.family = [“姐姐”,“哥哥”,“妹妹”];

}

function Desk(name,age){

Box.call(this,name,age)        //Desk 冒充 Box

}

var desk = new Desk( );

alert(desk.name);    //返回 Andy

alert(desk.family);   //返回 姐姐,哥哥,妹妹

PS:

① call和apply方法都可以实现继承,两者的第二个参数不同,call是一个个的参数列表

apply的第二个参数是数组。

例:Box.call(this,name,age);

Box.apply(this,[name,age]);

② 对象冒充只能继承构造里的信息

例:接上例添加:

Box.prototype.family = “家庭”;

alert(desk.family);    //继承不了,仍然返回 姐姐、哥哥、妹妹


3、组合继承法(对象冒充+原型链继承方式)

使用原型链实现对原型属性和方法的继承,使用对象冒充来实现对实例属性的继承

例:function Box(name,age){

this.name = name;

this.age = age;

}

Box.prototype.work = function(){

return  this.name+this.age+”运行中”;

}

function Desk(name,age){

Box.call(this,name,age)             //对象冒充,构造里继承

}

Desk.prototype = new Box( );        //原型链继承

var desk = new Desk(“Andy”,25);

alert(desk.work( ) );   //返回 Andy 25 运行中


小 结   

① 原型链继承中,包含引用类型值的原型的原型属性会被所有实例共享,并且创建子类型的实例时,不能向超类型的构造函数中传递参数,因此实践中很少会单独使用原型链。

② 对象冒充(借用构造函数法)中,可以通过call()或者apply()方法在新创建的对象上实行构造函数,解决了原型链继承法中共享和无法传参的问题。但对象冒充只能继承构造里的信息,会导致函数无法复用。

③ 组合继承中,使用原型链实现对原型属性和方法的继承,而通过借用构造函数实现对实例属性的继承,既能实现函数复用,又能保证每个实例都有自己的属性,因此,成为JavaScript常用的继承模式(唯一问题:超类型会被调用两次)


4、原型式继承(与原型链继承类似)

例://临时中转函数

function obj(o){      //o表示将要传递进入的一个对象

function  F( ){ }           // 临时新建的对象,用来储存传递过来的对象

F.prototype = o;        //将o对象实例赋值给F构造的原型对象

return new F( );

}

var box = {                     //相当于 var box = new Box();

name:”Andy”,

age:28,

family:[“哥哥”,“姐姐”]

}

var box1 = obj (box);    //相当于 var box1 = new F();

alert(box1.name);         //   返回 Andy

alert(box1.family);        //    返回 哥哥,姐姐

box1.family.push(“弟弟”);

alert(box1.family);        //    返回 哥哥,姐姐,弟弟

var box2 = obj(box);

alert(box2.family);        // 返回 哥哥,姐姐,弟弟

因此,原型式继承的问题是包含引用类型值的属性始终会共享相应的值


5、寄生式继承(原型式 + 工厂模式)

例:function obj(o){                  //与原型式继承相同,临时中转函数

function F(){}

F.prototype = o;

return new F();

}

function create(o){        //  创建寄生函数

var f = obj(o);

f.run = function(){

return this.name+"方法";

}

return f ;

}

var box = {

name:”Andy",

age:100,

family:["哥哥","姐姐"]

};

var box1 = create(box);

alert(box1.name)  //Andy

alert(box1.run());  //Andy 方法

此方法可以为对象添加函数,但也不能做到函数复用,与借用构造函数继承类似。


6、寄生组合式继承

function obj(o){

function F( ){};

F.prototype = o;

return new F( );

}

function create(box,desk){

var f = obj(box.prototype);

f.constructor = desk;    //调整原型构造指针

desk.prototype = f;

}

function Box(name,age){

this.name = name;

this.age = age;

}

Box.prototype.run=function(){

return  this.name+this.age +”启动”;

}

function Desk(name,age){

Box.call(this,name,age);    //对象冒充

}

create(Box,Desk);           //替代 Desk.prototype = new Box( );

var desk = new Desk(“Andy”,28);

alert(desk,run());    //弹出  Andy28启动

问题:组合继承是 js 最常用的继承方式,但组合继承的超类型会在使用过程中会被调用两次,一次在创建子类型时,一次在子类型构造函数内部,即:Desk.prototype =  new Box( );第一次调用;Box.call(this,name,age);第二次调用。

解决:寄生组合式继承则解决了超类型被调用两次的问题

时间: 2024-11-01 08:26:13

JavaScript学习笔记(三)—— 继承的实现的相关文章

JavaScript学习笔记(三)——this、原型、javascript面向对象

一.this 在JavaScript中this表示:谁调用它,this就是谁. JavaScript是由对象组成的,一切皆为对象,万物皆为对象.this是一个动态的对象,根据调用的对象不同而发生变化,当然也可以使用call.apply修改this指向的对象.它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用 1.1.JavaScript中函数与方法的区分 在面向过程的语言中我们习惯把完成某个特定功能的代码块称为“函数”或“过程”,当然过程一般没有返回值.在面向对象语言中我们把对象的功能

JavaScript学习笔记三:JavaScript对象

一.前言 对象的基本概念:Javascript提供了多个内建对象,比如String.Data.Array等等.对象指的是带有属性和方法的特殊数据类型 创建对象:创建JavaScript对象主要有两种不同的方法:第一.定义创建对象的实例:第二,使用函数来定义对象,然后创建新的对象 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.

前端乱煮之javascript学习笔记三

1 DOM即为文档对象模型,在html页面加载完成后,浏览器会创建页面的文档对象模型,它看来像是一棵树,有根节点,以及其他的节点. 而通过可编程的对象模型,javascript可以获得创建动态HTML的能力.比如,javascript可以改变HTML所有的元素.可以改变这些元素的属性.可以改变这些元素的样式和能对该页面内的事件作出反应. 2 要想对页面内的元素进行操作,首先就要获得这个元素.通常有三种获得元素的方法,分别是 通过Id来获得元素: 通过标签来获得元素: 通关类名来获得元素: 3 通

JavaScript学习笔记三:基本概念(1)

1. JS中的一切(变量.函数名.操作符等)都区分大小写.--true是boolean值,而True只是标识符. 2. JS语句以分号结尾,但不是必需的,原因: a. 结尾没有分号有时会导致压缩错误. b. 加上分号在某些情况下会为解析器提供方便,增进代码的性能. 3. 不同的ECMAScript版本对关键字和保留字的定义不同,但最好在JS代码中永远都不用任何关键字和保留字,以便与将来的ECMAScript版本兼容. 4. ECMAScript的变量是松散类型的,就是一个变量没有特定的类型限制,

javascript学习笔记(三) string对象中的正则表达式

1. search返回匹配到的位置(-1找不到) var str = 'html js' var pattern = /js/ str.search(pattern)    --------->5 2. Match str.match(pattern) --------['js'] /js/g -----> ["js", "js",,"js"] match vs exec match:非全局的情况下才会返回分组中匹配到的内容,全局匹配

javascript学习笔记---ECMAScript语法(引用类型)

引用类型通常叫做类(class). 本教程会讨论大量的 ECMAScript 预定义引用类型. 引用类型 引用类型通常叫做类(class),也就是说,遇到引用值,所处理的就是对象. 本教程会讨论大量的 ECMAScript 预定义引用类型. 从现在起,将重点讨论与已经讨论过的原始类型紧密相关的引用类型. 注意:从传统意义上来说,ECMAScript 并不真正具有类.事实上,除了说明不存在类,在 ECMA-262 中根本没有出现"类"这个词.ECMAScript 定义了"对象定

JavaScript学习笔记【2】表达式和运算符、语句、对象

笔记来自<JavaScript权威指南(第六版)> 包含的内容: 表达式和运算符 语句 对象 表达式和运算符 数组直接量中的列表逗号之间的元素可以省略,这时省略的空位会填充值undefined.元素列表末尾可以留下单个逗号,这时并不会创建一个新的值为undefined元素. 属性访问表达式,.identifier的写法只适用于要访问的属性名称是合法的标识符,并且需要知道要访问的属性的名字.如果属性名称是一个保留字或者包含空格和标识符,或是一个数字(对于数组来说),则必须使用方括号的写法.当属性

JavaScript学习笔记【3】数组、函数、服务器端JavaScript概述

笔记来自<JavaScript权威指南(第六版)> 包含的内容: 数组 函数 服务器端JavaScript概述 数组 数组是动态的:根据需要它们会增长或缩减,并且在创建数组时无须声明一个固定的大小或在数组大小变化时无须重新分配空间. 数组可能是稀疏的:索引不一定要连续的,它们之间可以有空缺. 通常,数组的实现是经过优化的,用数字索引来访问数组元素一般来说比访问常规的对象属性要快很多. 数组继承自Array.prototype中的属性,它定义了一套丰富的数组操作方法. 如果省略数组直接量中的某个

Java程序猿的JavaScript学习笔记(1——理念)

计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript学习笔记(3--this/call/apply) Java程序猿的JavaScript学习笔记(4--this/闭包/getter/setter) Java程序猿的JavaScript学习笔记(5--prototype) Java程序猿的JavaScript学习笔记(6--面向对象模拟) Java程

Java程序员的JavaScript学习笔记(14——扩展jQuery UI)

计划按如下顺序完成这篇笔记: Java程序员的JavaScript学习笔记(1--理念) Java程序员的JavaScript学习笔记(2--属性复制和继承) Java程序员的JavaScript学习笔记(3--this/call/apply) Java程序员的JavaScript学习笔记(4--this/闭包/getter/setter) Java程序员的JavaScript学习笔记(5--prototype) Java程序员的JavaScript学习笔记(6--面向对象模拟) Java程序员