一道有价值的JS继承面试题(js 继承 面试)

网友投稿 254 2022-06-12


题目

原题目来源于一个网友的问答

var A = function() {

this.name = 'apple';

}

A.prototype.getName = function() {

return this.name;

}

// 补充代码

var B = A.extend({

initialize: function() {

this.superclass.initialize.call(this);

this.total = 3;

},

say: function() {

return '我有' + this.total + '个' + this.getName()

}

});

var b = new B();

console.log(b.say()); //我有3个apple

分析

题目希望生成一个新的构造函数,B继承于A。(尽量不要更改A)

题目表达出希望有initialize方法实现构造函数继承,又需要原型继承。不难想到我们要用组合继承、寄生组合继承或者ES6继承。

如果所有的函数都可以使用extend方法生成一个新的构造函数,那方法的通用性会更强。

initialize的this指向显然要改成指向子类构造函数中的this。

解答

一. 要实现分析的第三点,不难想到使用函数的原型

Function.prototype.extend= Function.prototype.extend || function(obj) {}

二. initialize方法实现构造函数继承

Function.prototype.extend= Function.prototype.extend || function(obj) {

var self = this; //这里的this指向函数调用者,也可以是A

function SubClass() {

this.superclass = { initialize: self };

if (obj.initialize) {

obj.initialize.call(this); //处理this指向问题

}

}

return SubClass;

}

三. 原型继承并且添加新的原型方法

Function.prototype.extend= Function.prototype.extend || function(obj) {

var self = this; //这里的this指向函数调用者,也可以是A

function SubClass() {

this.superclass = { initialize: self };

if (obj.initialize) {

obj.initialize.call(this); //处理this指向问题

}

}

SubClass.prototype = new self();

SubClass.prototype.constructor = SubClass;

for(var key in obj){

if(key !== 'initialize'){

SubClass.prototype[key] = obj[key]

}

}

return SubClass;

}

问题

添加较为严谨的类型判断

组合继承是存在一定问题的(见javascript高级教程第六章),如果能用ES6继承会更好。

改进

function inherits(subClass, superClass) { // ES6继承

if (typeof superClass !== "function" && superClass !== null) {

throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);

}

subClass.prototype = Object.create(superClass && superClass.prototype, {

constructor: {

value: subClass,

enumerable: false,

writable: true,

configurable: true

}

});

if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;

}

function getType(obj) {

return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();

}

Function.prototype.extend= Function.prototype.extend || function(obj) {

var self = this; //这里的this指向函数调用者,也可以是A

function SubClass() {

this.superclass = { initialize: self };

if (getType(obj) === 'object' && getType(obj.initialize) === 'function') {

obj.initialize.call(this); //处理this指向问题

}

}

inherits(SubClass, self);

for (var key in obj) {

if (key !== 'initialize') {

SubClass.prototype[key] = obj[key]

}

}

return SubClass;

}

总结:

该题目考查了几个重要的知识点:原型,继承,闭包,this指向。是一道比较值得去好好思考的题目。

希望有更好的解决方案出现。

来自:https://segmentfault.com/a/1190000008888142


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:JavaScript引用是如何工作的(javascript引用方式)
下一篇:浅析前端页面渲染机制(前端处理数据渲染页面的方式)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~