前端面试题:继承的实现 ゝ一世哀愁。 2022-11-28 13:54 127阅读 0赞 这个是让我崩溃的那个面试题,不是说这个题有多难,而是说自己粗心吧,只是简单的看了实现继承的方式有原型继承,构造函数继承,组合继承,class继承,但是怎么实现的都不知道。昨天面试完总结了一下,索性就把它写成文章,分享加自我回顾。 **1、原型链继承** 首先说的继承就是原型链的继承,因为在问我继承前先问了原型和原型链,原型链的集成有什么特点呢,就是子类的prototype指向父类的一个实例。这样的话子类没有的属性方法会在他的原型中去找到,就是说子类的实例的\_\_proto\_\_会指向父类的实例,这个时候就可以拿到父类的属性和方法,代码更好理解: function father(phone,sex){ this.phone = phone; this.sex = sex; this.say = function(){ console.log("这是你爹的方法"); } } function son(name,age){ this.name = name; this.age = age; this.eat = function(){ console.log("吃"); } } son.prototype = new father("110","女"); var tomCat = new son("tomcat",15); console.log(tomCat); 每种继承方式都有它自己的优缺点,首先来说原型链继承的优点,其实他最大的优点就是实现的方式简单易用,只需要把子类的\_\_proto\_\_指向父类的一个实例即可,缺点呢也是很明显的,首先呢是无法实现多继承,其次主要因为来自原型对象的所有属性被所有实例共享,而且创建子类实例时,无法向父类构造函数传参,要想为子类新增属性和方法,必须要在`Student.prototype = new Person()` 之后执行,不能放到构造器中。 ![原型链继承结果][20200818143959991.png] **2、构造函数继承** 构造函数的继承比较依赖call和apply,它的实现方式是在子类内部调用父类方法,并通过call改变它的作用域,指向子类的this,从而把父类的方法拿过来。 function father2(phone,sex){ this.phone = phone; this.sex = sex; this.say = function(){ console.log("这是你爹的方法"); } } function son2(name,age){ father2.call(this,"120","男") this.name = name; this.age = age; this.eat = function(){ console.log("吃"); } } var jerui = new son2("tomcat",15); console.log(jerui); 构造函数的继承解决了原型链继承中子类实例共享父类引用属性的问题,并且创建子类实例时,可以向父类传递参数,而且可以实现多继承,就是多call几个爹,但是也有它的缺点,就是它的实力不是父类的实例,而且只能继承父类的属性方法,父类的原型上的无法继承,无法实现函数复用,每个子类都有父类实例函数的副本,影响性能。 ![20200818145151100.png][] ** 3、原型链+构造函数的组合继承** 特点呢就是通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用,就是把上边两种方式的优点结合到一块实现的。 function Person(name, age) { this.name = name, this.age = age, this.setAge = function () { } } Person.prototype.setAge = function () { console.log("111") } function Student(name, age, price) { Person.call(this,name,age) this.price = price this.setScore = function () { } } Student.prototype = new Person() Student.prototype.constructor = Student//组合继承也是需要修复构造函数指向的 Student.prototype.sayHello = function () { } var s1 = new Student('Tom', 20, 15000) var s2 = new Student('Jack', 22, 14000) console.log(s1) console.log(s1.constructor) //Student console.log(p1.constructor) 相当于是把上边两种方式的优点集于一身,缺点的话就是调用了两次父类构造函数,生成了两份实例。 **4、组合继承优化** 通过父类原型和子类原型指向同一对象,子类可以继承到父类的公有方法当做自己的公有方法,而且不会初始化两次实例方法/属性,避免的组合继承的缺点。 function Person(name, age) { this.name = name, this.age = age, this.setAge = function () { } } Person.prototype.setAge = function () { console.log("111") } function Student(name, age, price) { Person.call(this, name, age) this.price = price this.setScore = function () { } } Student.prototype = Person.prototype Student.prototype.sayHello = function () { } var s1 = new Student('Tom', 20, 15000) console.log(s1) **5、ES6中的class继承** ES6中引入了class关键字,class可以通过extends关键字实现继承,还可以通过static关键字定义类的静态方法,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。 ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。 需要注意的是,class关键字只是原型的语法糖,JavaScript继承仍然是基于原型实现的。 class father3{ constructor(phone,sex){ this.phone = phone; this.sex = sex; } showName(){ console.log("这是你爹的方法"); console.log(this.phone,this.sex); } } let houdie = new father3("爸爸","40"); console.log(houdie); class son3 extends father3{ constructor(name,age,salary){ super(name,age); this.salary = salary; } showName(){ console.log("这是孩子自己的方法"); console.log(this.name,this.age,this.salary); } } let baby = new son3("baby","2","helloWorld"); console.log([baby]); class继承语法简单易懂,操作更方便,但是并不是所有的浏览器都支持class关键字。 上边两种组合继承不是我自己敲的,因为原型链继承和构造函数继承看懂了,上边两个这个就懂了,今天就这样了,继续努力。 [20200818143959991.png]: /images/20221124/929fb571590e461e8f6ebe1f6bb9bfc4.png [20200818145151100.png]: /images/20221124/b7e2bb3541db4116b035fa8da097e82c.png
相关 前端面试题 事件代理优点有哪些? 可以为将来元素绑定事件 减少事件注册 什么是事件对象? 保存调用该事件详细信息的一个参数,没有固定命名 li与li之间有看不见的 本是古典 何须时尚/ 2022年05月21日 00:23/ 0 赞/ 274 阅读
相关 前端面试题 [前端面试题《CSS》][CSS] [前端面试题《JS》][JS] [前端面试题《vue》][vue] [前端面试题《网络&浏览器》][L £神魔★判官ぃ/ 2022年05月15日 18:12/ 0 赞/ 457 阅读
相关 前端面试题 一、532道前端真实大厂面试题 1.express和koa的对比,两者中间件的原理,koa捕获异常多种情况说一下 2.你项目里用到第三方登录涉及的oAuth(JWT)协 以你之姓@/ 2022年05月09日 12:04/ 0 赞/ 292 阅读
相关 前端面试题 2018 vue前端面试题 1、active-class是哪个组件的属性?嵌套路由怎么定义? vue-router模块的router-link组件 2、怎么定义 灰太狼/ 2022年03月26日 14:10/ 0 赞/ 218 阅读
相关 前端面试题 > 小编推荐:[Fundebug][]提供JS错误监控、微信小程序错误监控、微信小游戏错误监控,Node.j错误监控和Java错误监控。真的是一个很好用的错误监控费服务,众多大 水深无声/ 2022年02月21日 14:29/ 0 赞/ 422 阅读
相关 前端面试题 今天看到一份某大厂的前端面试题,自己看了看挺简单的,由于我是即将要面临找工作实习的大学生,所以想分享给大家。 1. 给String定义一个doRepate方法,该方法接受一 ╰半橙微兮°/ 2022年01月19日 02:55/ 0 赞/ 307 阅读
相关 前端面试题 1. css的三种盒模型 c s s 的 两 种 盒 模 型 = \{ w 3 c 标 准 盒 模 型 I E 盒 模 型 弹 性 盒 模 型 css的两种盒模型=\\ 古城微笑少年丶/ 2021年11月11日 07:44/ 0 赞/ 393 阅读
相关 前端面试题 前端面试题汇总 一、HTML和CSS 21 1. 你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么? 21 2. 每个HTML文件里开头都有个很重要的东西,Do 不念不忘少年蓝@/ 2021年11月05日 04:44/ 0 赞/ 550 阅读
相关 前端面试题 对闭包的理解 [http://www.ruanyifeng.com/blog/2009/08/learning\_javascript\_closures.html][h 蔚落/ 2021年10月19日 00:20/ 0 赞/ 380 阅读
相关 前端面试题 版权声明:本文为博主【小北】原创文章,如要转载请评论回复。个人前端公众号:前端你别闹,JS前端实用开发QQ群 :147250970 欢迎加入~! ![Center][] 古城微笑少年丶/ 2021年10月08日 06:16/ 0 赞/ 423 阅读
还没有评论,来说两句吧...