JavaScript面向对象-基于函数伪造的方式实现继承 - Web前端
作者:98wpeu发布时间:2026-08-29分类:网页前端技术浏览:6
由于基于原型链实现继承的方式存在一些缺点,所以人们采用了另外一种方式来实现继承——基于函数伪造的方式实现继承。这个技术的思想是在子类构造函数的内部调用父类的构造函数。
基于函数伪造的方式实现继承的实现方式
因为在javascript中,函数是在特定环境中执行代码的对象,所以我们可以使用call()或apply()方法来在子类对象上执行父类对象的构造函数。来看下面的例子:
/* 创建父类 */
function parent(){
this.color = ["red","blue"];
}
/* 创建子类 */
function Child(){
// 继承父类的属性
Parent.call(this);
}
在上面的代码中,我们首先创建了一个父类Parent,然后创建一个子类Child,并在子类的内部使用Parent.call(this);来完成继承。
在函数的属性一文中,我们已经介绍了call()和APPly()方法,这两个方法的作用是在特定的作用域中调用函数,也就是说这两个方法可以通过函数名称来调用函数。在这里我们在Child的内部使用Parent.call(this);来完成继承,这句话的意思是在子类中调用父类的构造函数,此时的this指的是Child对象(在Child中的this应该是执行Child的对象),所以就等于在Child中有了一句this.color = ["red","blue"];,也就是等于在Child中有了this.color属性,这样也就变相的完成了继承。
我们可以通过下面的方法来进行验证:
var c1 = new Child(); //创建子类对象c1
c1.color.push("Green"); //为c1添加新的颜色
console.info(c1.color); //控制台输出:red,blue,Green
var c2 = new Child(); //创建子类对象c2
console.info(c2.color); //控制台输出:red,blue
在上面的代码中,我们创建了子类对象c1,并为它添加新的颜色”Green“,所以会在控制台中输出:"red,blue,Green"。然后我们又创建了对象c2,因为没有为它添加新的颜色,所以它只会在控制台中输出继承自父类的颜色:"red,blue"。
每调用一次new Child就等于执行了一次对象属性的设定,此时,每个对象的空间中都有color属性,而不会在原型中存在,所以color不会被共享。这样就解决了原型链继承中引用类型变量存在的问题。
子类构造函数
原型链继承的另外一个缺点是无法从子类中调用父类的构造函数,这样就没有办法把子类中的属性赋值到父类中。通过函数伪造的方式可以很好的解决这个问题。来看下面的例子:
// 创建父类
function Parent(name){
this.name = name;
}
//创建子类
function Student(name,age){
//使用伪造的方式就可以把子类的构造函数参数传递到父类中
Parent.call(this,name); //调用父类的属性
this.age = age;
}
var s1 = new Student("Leon",22);
var s2 = new Student("Ada",25);
console.info(s1.name + "," + s1.age); // 控制台输出:Leon,22
console.info(s2.name + "," + s2.age); // 控制台输出:Ada,25
在上面的代码中,子类Student通过函数伪造的方式调用父类的name属性,实际上是为子类添加一个name属性。在这里,call()方法将Student类的参数name传递到父类中,完成的操作相当于this.name = name;。而这个name属性是子类的name属性,而不是父类的name属性。
基于函数伪造实现继承存在的问题
在上面的讨论中,我们讲的只是子类继承父类的属性,那么子类如何继承父类的方法呢?在前面我们说过,通常我们将方法放到原型中设置,例如父类中有一个say()方法,代码如下:
// 创建父类
function Parent(name){
this.name = name;
}
// 父类的say()方法
Parent.prototype.say = function(){
console.info(this.name);
}
//创建子类
function Student(name,age){
Parent.call(this,name);
this.age = age;
}
由于使用函数伪造的方式不会完成子类Student的原型指向父类Parent,所以在子类继承父类之后,say()方法是不存在的。解决这个问题的方法是,将say()方法放置到Parent中使用this关键字来创建。
// 创建父类
function Parent(name){
this.name = name;
// 父类的say()方法
this.say = function(){
console.info(this.name);
}
}
//创建子类
function Student(name,age){
Parent.call(this,name);
this.age = age;
}
这样做虽然可以使子类继承父类的say()方法,但是又产生了另外一个问题:每次创建子类对象的时候都会生成一个say()方法,会占用大量的内存空间。
由于基于函数伪造的方式实现继承也存在缺陷,所以我们也不会单独使用这种方式来完成继承,而是会使用基于组合的方式实现继承,我们将在下一篇文章中介绍这种继承方式。
返回javascript教程主目录>>
相关推荐
- 百度WEB前端JavaScript编程题和HTML/CSS面试题 - Web前端
- SVG基础 | SVG tspan 元素 - Web前端
- SVG基础 | 绘制SVG连接标记markers - Web前端
- Javascript实例教程:网页中移动拖拽的JS属性 - Web前端
- 【SVG】SVG的viewport,viewBox,preserveAspectRatio - Web前端
- 使用node.js 进行服务器端JavaScript编程 - Web前端
- JavaScript浏览器对象模型概述 - Web前端
- 优化网站首页轮播广告之心得 - Web前端
- Node.js 给前端带来了什么 - Web前端
- HTML5技术革命:迎接HTML5.1,展望HTML5.2 - Web前端
- 网页前端技术排行
-
- 1[Web前端]用javascript实现默认图片替代未显示的图片 - Web前端
- 2分析Iconfont-阿里巴巴矢量常用图标库 - Web前端
- 3jQuery实例教程:制作网页中可折叠的面板 - Web前端
- 4基于jquery的滚动条滚动固定div(附演示下载) - Web前端
- 5【第六章】Foundation之按钮和下拉功能 - Web前端
- 6jQuery编写widget的一些技巧分享 - Web前端
- 7分享精心挑选的12款优秀jQuery Ajax分页插件和教程 - Web前端
- 8jQuery实现鼠标移到元素上动态提示消息框效果 - Web前端
- 9在Mac/PC上远程调试iPhone/iPad上的网页 - Web前端
- 最近发表
-
- WordPress随机显示特色图片插件:Random Post Thumbnails
- KeePass实现Chrome浏览器自动填充密码方法一
- LNMP一键包nginx 301强制跳转到https教程
- KeePass实现Chrome浏览器自动填充密码方法二
- #建站# 免费的VPS管理软件Xshell8/Xftp8中文版下载
- 使用Xshell 8连接VPS教程_电脑登录vps的方法
- WordPress评论界面添加烟花????效果
- 不同浏览器书签同步方案:坚果云+Floccus_详细使用教程
- iOS端KeePassXC客户端APP:Strongbox Password Safe
- 给WordPress评论中的Gravatar头像图片添加ALT属性


