JS中的继承方式总结
1. 原型链继承(又称类继承)
Child.prototype = new Parent();
function Parent (name, age) {
this.name = name;
this.age = age;
}
Parent.prototype.say = function(){
console.log('hello, my name is ' + this.name);
};
function Child() {
}
Child.prototype = new Parent('pursue');
var child1 = new Child();
child1.say(); //hello, my name is pursue
var child2 = new Child();
console.log(child1.say === child2.say);//true
console.log(child1.name === child2.name);//true
通过子类的原型prototype对父类实例化实现。利用将父类实例赋值给子类原型,达到继承的目的:子类原型可访问父类原型上的属性和方法 以及 父类构造函数中复制的属性和方法(类的构造函数中的属性和方法会在实例化对象的时候复制的该实例化对象中去)
Child.prototype instanceof Parent //true
缺点一:父类的共有属性是引用类型时,子类的一个实例更改子类原型从父类构造函数继承来的该属性时,会直接引起子类其他实例中该继承属性值的变化。
缺点二:子类通过原型prototype实现对父类的实例化而实现继承,因此不能在创建父类的时候给父类传参,所以在实例化父类的是无法对父类构造函数内的属性进行初始化。
2. call(thisObj, param1, param2,...) // 构造函数继承
function Parent(username){
this.username = username;
this.hello = function(){
alert(this.username);
}
}
Parent.prototype.show = function() {console.log("show me")}
function Child(username,password){
Parent.call(this,username);
this.password = password;
this.world = function(){
alert(this.password);
}
}
var parent = new Parent("zhangsan");
var child = new Child("lisi","123456");
parent.hello();
child.hello();
child.world();
child.show(); //TypeError
3. apply(thisObj, [param1,param2,...]) // 构造函数继承
function Parent(username){
this.username = username;
this.hello = function(){
alert(this.username);
}
}
Parent.prototype.show = function() {console.log("show me")}
function Child(username,password){
Parent.apply(this,new Array(username));
this.password = password;
this.world = function(){
alert(this.password);
}
}
var parent = new Parent("zhangsan");
var child = new Child("lisi","123456");
parent.hello();
child.hello();
child.world();
child.show(); //TypeError
2,3 为构造函数式继承方式,通过在子类的构造函数作用环境中执行一次父类的构造函数实现,优化了 1 中的两个缺点,但是由于是通过构造函数继承的,故父类原型中的方法子类是无法调用到的,所以有了下面的组合继承方式。
4. 组合继承(call+原型链 / apply+原型链)
function Parent(hello){
this.hello = hello;
}
Parent.prototype.sayHello = function(){
alert(this.hello);
}
function Child(hello,world){
Parent.call(this,hello);//利用 call 方法 将父类的属性继承过来
//Parent.apply(this,new Array(hello));//利用 apply 方法 将父类的属性继承过来
this.world = world;//新增一些属性
}
Child.prototype = new Parent();//将父类原型中的的方法继承过来
Child.prototype.sayWorld = function(){//新增一些方法
alert(this.world);
}
var c = new Child("zhangsan","lisi");
c.sayHello();
c.sayWorld();
① 在子类构造函数中执行父类构造函数,② 在子类原型上实例化父类
5.寄生组合继承,与4相似,只是将原型链换做了Object.create(Parent.prototype)
function Parent(hello){
this.hello = hello;
}
Parent.prototype.sayHello = function(){
alert(this.hello);
}
function Child(hello,world){
Parent.call(this,hello);//利用 call 方法 将父类的属性继承过来
//Parent.apply(this,new Array(hello));//利用 apply 方法 将父类的属性继承过来
this.world = world;//新增一些属性
}
Child.prototype = Object.create(Parent.prototype);//将父类的方法继承过来
Child.prototype.sayWorld = function(){//新增一些方法
alert(this.world);
}
var c = new Child("zhangsan","lisi");
c.sayHello();
c.sayWorld();
6.扩展Object类
Object.prototype.方法名 = function (parentObject) {
for(var attr in parentObject) {
this[attr] = parentObject[attr];
}
}
function Parent (name) {
this.name = name
this.syaHi = function() {
console.log('name is '+this.name);
}
}
function Child(pwd) {
this.pwd = pwd;
this.info = function() {
console.log(this.name, this.pwd);
}
}
Object.prototype.show = function(parentObject) {
for (var attr in parentObject) {
this[attr] = parentObject[attr];
}
}
var p = new Parent('zhangsan');
var c = new Child(12345);
c.show(p);
c.syaHi(); // zhangsan
c.info(); // zhangsan,12345
7. 对象冒充 在B(子类)的构造函数中,定义属性 bb = A(父类)的构造函数,在B的构造函数的最后再将bb删除
function Parent (name) {
this.name = name
this.show = function() {
console.log('name is '+this.name);
}
}
function Child(name) {
this.method = Parent; // 将Parent类的构造函数赋值给Child的一个方法
this.method(name); // 这里相当于把Parent的构造函数当作普通函数调用了一次,对象冒充
delete this.method; // 一处这个用来做对象冒充功能的method
}
var p = new Parent('父类');
p.show(); // name is 父类
var c = new Child('子类');
c.show(); // name is 子类
JS中的继承方式总结的更多相关文章
- JS中对象继承方式
JS对象继承方式 摘自<JavaScript的对象继承方式,有几种写法>,作者:peakedness 链接:https://my.oschina.net/u/3970421/blog/28 ...
- js中常见继承方式
1.原型模式 function Father(){ this.property = true; } Father.prototype.getValue = function(){ return thi ...
- js中的继承和重载
js中有三种继承方式:一.通过原型(prototype)实现继承 二.借用构造函数式继承,可分为通过call()方法实现继承和通过apply()方法实现继承 仅仅通过原型继承我们可以发现在实例化子 ...
- js中实现继承的几种方式
首先我们了解,js中的继承是主要是由原型链实现的.那么什么是原型链呢? 由于每个实例中都有一个指向原型对象的指针,如果一个对象的原型对象,是另一个构造函数的实例,这个对象的原型对象就会指向另一个对象的 ...
- 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承
ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...
- JS中的继承(上)
JS中的继承(上) 学过java或者c#之类语言的同学,应该会对js的继承感到很困惑--不要问我怎么知道的,js的继承主要是基于原型(prototype)的,对js的原型感兴趣的同学,可以了解一下我之 ...
- JS中的继承(下)
JS中的继承(下) 在上一篇 JS中的继承(上) 我们介绍了3种比较常用的js继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...
- JS中写继承的方式
有父子两个函数,代表两个类: var parent = function(){} var child = function(){} 一.直接继承 child.prototype = new paren ...
- JS中的继承实现方式
第一种:通过prototype来实现 prototype.html <!DOCTYPE html><html lang="en"><head> ...
随机推荐
- Python之freshman07 面向对象编程jinjie
本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个支持多用户在线的FTP程 经典类vs新式类 把下面代码 ...
- JavaWeb学习笔记(二)—— Tomcat服务器
一.Web开发概述 1.1 Web开发中常见的概念 [B/S系统和C/S系统] Brower/Server:浏览器 服务器 系统 ----- 网站 Client/Server:客户端 服务器 系统 - ...
- 编写高质量代码:Web前端开发修炼之道(一)
最近老大给我们买来一些技术方面的书籍,其实很少搬着一本书好好的完整的看完过,每每看电子档的,也是打游击式的看看这章,瞅瞅那章,在那5本书中挑了一本比较单薄的<编写高质量代码web前端开发修炼之道 ...
- C++_类和动态内存分配6-复习各种技术及队列模拟
知识点: 队列:是一种抽象的数据类型(Abstract Data Type),可以存储有序的项目序列. 新项目被添加在队尾,并可以删除队首的项目.队列有些像栈.栈是在同一端进行添加和删除.这使得栈是一 ...
- LeetCode15. 三数之和
15. 三数之和 描述 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中 ...
- abp 后台项目在IIS 中运行
安装 Current .NET Core Hosting Bundle installer (direct download)
- Kibana6.x.x源码分析--如何使用kibana的savedObjectType对象
默认kibana插件定义了三种保存实体对象[savedObjectType],如下图所示: 要使用只需要在自己定义的app的uses属性中添加上:savedObjectTypes 即可,如下图所示: ...
- poj1182 食物链 带权并查集
题目传送门 题目大意:大家都懂. 思路: 今天给实验室的学弟学妹们讲的带权并查集,本来不想细讲的,但是被学弟学妹们的态度感动了,所以写了一下这个博客,思想在今天白天已经讲过了,所以直接上代码. 首先, ...
- Hibernate复合主键的注解
[转自] http://blog.csdn.net/happylee6688/article/details/17636801 最近做项目用到了Hibernate框架,采用了纯面向对象的思想,使用OR ...
- Linux设备驱动开发基础--阻塞型设备驱动
1. 当一个设备无法立刻满足用户的读写请求时(例如调用read时,设备没有数据提供),驱动程序应当(缺省的)阻塞进程,使它进入等待(睡眠)状态,知道请求可以得到满足. 2. Linux内核等待队列:在 ...