三分钟搞定JS继承
发布日期:2022-02-22 16:04:46
浏览次数:24
分类:技术文章
本文共 3694 字,大约阅读时间需要 12 分钟。
一、原型链继承
- js中无法实现接口继承,依靠原型链来实现继承
基本思想:通过改变prototype的指向形成实例和原型之间的原型链
instanceSub->subType.prototype(instanceSuper)->superType.prototype-> Object.prototype->null
- 实现步骤
- 子对象的原型是父对象的实例
subType.prototype = instanceSuper;
或subType.prototype=new superType();
- 父对象的实例上添加 constructor 属性 指向 subType
subType.prototype.constructor = subType;
改变prototype
- 动态修改prototype的属性时,会影响所有已经创建和新创建的实例。
- 重写prototype,即将prototype赋值为新的对象(对象字面量形式)时,不会影响已经创建的实例,会影响后序创建的实例
function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = function() { return this.property; } function subType() { this.subproperty = false; } var instanceSuper = new SuperType(); subType.prototype = instanceSuper; //子对象的原型是父对象的实例 //SuperType的实例作为 subType的原型 subType.prototype.constructor = subType;//添加 constructor 属性 指向 subType //子对象的原型设置为父对象的实例后,再向子对象原型添加方法 subType.prototype.getSubValue = function() { return this.subproperty; } var instanceSub = new subType(); //子对象能够继承到父对象的方法 console.log(instanceSub.getSuperValue()); //true console.log(instanceSub.getSubValue()); //false
原型链的问题
1. 原型链上的属性都是共享的,包含引用类型值(eg:数组类型)的原型属性会被所有实例共享,一改全改2. 创建子类型的实例时 ,不能向父类型的构造函数中传递参数3. 解决:使用构造函数解决原型链继承的问题
二、构造函数继承
基本思想:在子对象的构造函数内部调用父类的构造函数
function SubType(type, price) { SuperType.call(this, type);//调用父类构造方法实现继承,同时可以传参 }
- 实例本身不能继承构造函数,实例可以使用构造函数中的属性和方法是由于this
构造函数实现继承的问题
- 实例继承自构造函数,而构造函数原型上的属性和方法对实例对象不可见.
- 构造函数模式的问题:方法都在构造函数中定义,无法复用
三、原型+构造函数组合继承(常用)
基本思想:使用原型链实现对原型属性和方法的继承,构造函数实现对实例属性的继承
原型+构造函数组合继承的问题: 调用两次超类构造函数。1.创建子类原型 2. 在子类构造内部调用父类构造
function SuperType(name) { this.name=name; this.color = ['red', 'green', 'blue']; } SuperType.prototype.sayName=function(){ console.log(this.name); } function SubType(name,age) { this.age = age; SuperType.call(this,name);//调用父类构造方法实现继承. } //继承构造函数原型上的属性和方法 SubType.prototype=new SuperType();//调用父类构造函数 SubType.prototype.constructor=SubType; SubType.prototype.sayAge=function(){ console.log(this.age); } var sub = new SubType('lily',18); sub.color.push('black'); console.log(sub.color);//["red", "green", "blue", "black"] var sub2 = new SubType('nacy',12); console.log(sub2.color);//["red", "green", "blue"]
四、原型式继承
基本思想:创建一个生成临时构造函数的函数,借助原型,基于已有的对象创建新对象
function object(o){ function F(){ };//创建临时构造函数 F.prototype=o;//将临时构造函数的原型设置为超类的对象. return new F();//返回临时构造函数的新实例 } var person2=object(person);//则 person2 的原型为person
-
Object.create() 方法规范化了原型式继承,可以使用Object.create()替换object函数
-
Object.create() 是一个系统内置的函数,接收一个参数,一般是对象,返回新创建的对象,并且对象的原型指向传入的参数。
创建一个空对象,空对象的原型,是传入的参数。 -
Object.create(null); null没有原型,没有prototype属性 ,所以没有toString方法
-
使用bind函数将函数指向为null后,该函数也没有prototype属性。
原型式继承的问题
- 引用类型值的属性会被所有实例共享
五、寄生式继承
基本思想:原型式继承+工厂模式(创建一个仅用于封装继承过程的函数,该函数在内部为对象添加属性和方法,然后返回对象)
寄生式继承的问题:不能做到函数复用
function object(o){ function F(){ }; F.prototype=o;//将临时构造函数的原型设置为超类的对象. return new F(); } function createAnother(original){ var clone=object(original); clone.sayHi=function(){ //添加函数后返回该对象,函数不共享 console.log('hi'); } return clone; } var person={ name:'张三', friends:['lily','nacy','tom'] } var person2=createAnother(person); person2.sayHi();
六、寄生组合式继承(引用类型的理想继承)
基本思想: 寄生式继承+组合继承
- 构造函数 继承 属性;原型链混成形式 继承 方法
function object(o){ function F(){ }; F.prototype=o;//将临时构造函数的原型设置为超类的对象. return new F(); } //创建超类构造函数的副本,赋值给子类型的原型 function inheritPrototype(subType,superType){ //两个参数:子类构造函数,父类构造函数 var prototype=object(superType.prototype);//创建超类型原型的副本 prototype.constructor=subType; subType.prototype=prototype;//将新创建的对象赋值给子类型的原型 }
转载地址:https://blog.csdn.net/Conradine_Lian/article/details/105299923 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月07日 10时24分36秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
领扣LintCode算法问题答案-1283. 翻转字符串
2019-04-27
领扣LintCode算法问题答案-1285. 四的乘方
2019-04-27
领扣LintCode算法问题答案-1294. 3的幂
2019-04-27
信息资源规划
2019-04-27
oracle中的schema和表空间
2019-04-27
某大型企业在全国各城市共有40个左右的分支机构
2019-04-27
在JavaScript中控制链接的点击
2019-04-27
系统安全
2019-04-27
Redis远程连接和口令验证
2019-04-27
java实现一个文件上传接口
2019-04-27
精益创业
2019-04-27
react获取并设置虚拟DOM
2019-04-27
持续集成与DevOps
2019-04-27
mysql一主一从读写分离真的可以提高性能吗?
2019-04-27
CoffeeScript里的字符串插值
2019-04-27
Linux下查看history里的某种命令
2019-04-27
CLR程序里引用System.Web.dll
2019-04-27
case 用在 UPDATE
2019-04-27
Localhost与数据库连接
2019-04-27
买酱油与软件工程阶段划分
2019-04-27