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> ...
随机推荐
- Octave安装符号工具箱
1.国内访问Octave的代码包不稳定,可以访问网址http://sourceforge.mirrorservice.org/o/oc/octave/Octave%20Forge%20Packages ...
- HTML <form> target 属性
浏览器支持 所有主流浏览器都支持 target 属性. 定义和用法 target 属性规定一个名称或一个关键词,指示在何处打开 action URL,即在何处显示提交表单后接收到的响应. target ...
- Apache 去掉 www
1 用phpstudy的网友打开“其他选项菜单”- “配置文件”-httpd-conf.找到 #LoadModule rewrite_module modules/mod_rewrite.so 把这一 ...
- python之函数(一)
python有很多内置函数,可以直接调用.比如type(), len(), range(),max(), min(), filter().内置函数我们就先不多提,我们主要介绍自定义函数. 1. 函数的 ...
- LeetCode记录之21——Merge Two Sorted Lists
算法和数据结构这东西,真的是需要常用常练.这道看似简单的链表合并题,难了我好几个小时,最后还是上网搜索了一种不错算法.后期复习完链表的知识我会将我自己的实现代理贴上. 这个算法巧就巧在用了递归的思想, ...
- Kibana6.x.x---编译源码,在执行优化任务时,报警告
wangxuan@tryman:/home/kibana_git/kibana6.2.2$ yarn release yarn run v1.5.1 $ grunt release Running & ...
- 【算法笔记】B1009 说反话
1009 说反话 (20 分) 给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80 的字符串.字符串由若干单词和若干空格 ...
- vue控制父子组件渲染顺序
在父组件中,如下图渲染子组件,那如何在父组件中加入一些数据获取逻辑且能控制子组件渲染呢. 就是像在上图中红框圈起来的那样,挂个 ok(其他你自己定义的也可以) 参数,同时在父组件的任何生命周期中去改变 ...
- [转] Scala 2.10.0 新特性之字符串插值
[From] https://unmi.cc/scala-2-10-0-feature-string-interpolation/ Scala 2.10.0 新特性之字符串插值 2013-01-20 ...
- 使用Maven运行Java main的3种方式使用Maven运行Java main的3种方式
maven使用exec插件运行java main方法,以下是3种不同的操作方式. 一.从命令行运行 1.运行前先编译代码,exec:java不会自动编译代码,你需要手动执行mvn compile来完成 ...