如何在伪类式继承的子类实例化时调用指定函数?
修复伪类式继承下Blinky Dancer的闪烁效果问题
你的代码里有几处关键问题导致闪烁效果没触发,下面逐个说明并给出修复后的完整代码:
问题点梳理
- 代码顺序搞反了:子类
makeBlinkyDancer的原型继承代码写在了父类makeDancer的原型方法定义之前,导致子类根本没继承到父类的step方法。 - 父类构造函数缺核心逻辑:
- 没把
timeBetweenSteps存到实例里,step函数拿不到定时器间隔时间 - 没调用
setPosition设置初始位置,dancer会卡在默认位置不动 - 没启动
step函数,定时器压根没开始跑
- 没把
- 父类
step函数调用错误:setTimeout里用了未定义的step变量,得调用实例自身的step方法并绑定正确上下文 - 子类保存父类方法时机不对:子类还没完成原型继承就去拿
step方法,拿到的是undefined
修复后的完整代码
$(document).ready(function() { window.dancers = []; $('.addDancerButton').on('click', function(event) { var dancerMakerFunctionName = $(this).data('dancer-maker-function-name'); console.log(dancerMakerFunctionName); var dancerMakerFunction = window[dancerMakerFunctionName]; var dancer = new dancerMakerFunction( $("body").height() * Math.random(), $("body").width() * Math.random(), Math.random() * 1000 ); $('body').append(dancer.$node); window.dancers.push(dancer); // 可选:把实例存到全局数组方便后续管理 }); }); // 先定义父类,再实现子类 var makeDancer = function(top, left, timeBetweenSteps) { this.$node = $('<span class="dancer"></span>'); // 把间隔时间存到实例属性,step函数要用到 this.timeBetweenSteps = timeBetweenSteps; // 初始化时设置位置 this.setPosition(top, left); // 启动定时循环 this.step(); }; makeDancer.prototype.step = function() { // 用箭头函数确保this指向当前dancer实例,也可以用this.step.bind(this) setTimeout(() => this.step(), this.timeBetweenSteps); }; makeDancer.prototype.setPosition = function(top, left) { var styleSettings = { top: top, left: left, position: 'absolute' // 必须加绝对定位,否则top/left样式不生效 }; this.$node.css(styleSettings); }; // 定义子类BlinkyDancer var makeBlinkyDancer = function(top, left, timeBetweenSteps) { // 调用父类构造函数,继承实例属性与初始化逻辑 makeDancer.call(this, top, left, timeBetweenSteps); }; // 让子类原型继承父类原型 makeBlinkyDancer.prototype = Object.create(makeDancer.prototype); // 修正constructor指向,避免原型链混乱 makeBlinkyDancer.prototype.constructor = makeBlinkyDancer; // 先保存父类的step方法,后续重写时要调用 var oldStep = makeBlinkyDancer.prototype.step; // 重写子类step方法,添加闪烁逻辑 makeBlinkyDancer.prototype.step = function() { // 调用父类step方法,保持定时循环 oldStep.call(this); // 切换节点显示/隐藏,实现闪烁效果 this.$node.toggle(); };
关键修复说明
- 调整代码顺序:先完成父类的构造函数和原型方法定义,再实现子类,确保子类继承时父类原型已经包含完整的
step方法。 - 父类构造补全:
- 新增
this.timeBetweenSteps = timeBetweenSteps保存间隔参数 - 调用
this.setPosition设置初始位置,同时补充position: 'absolute'样式,没有这个属性的话top/left控制不会生效 - 调用
this.step()启动定时器循环,让dancer创建后自动开始执行逻辑
- 新增
- 修复父类step函数:用箭头函数绑定上下文,确保
setTimeout里的this始终指向当前dancer实例,不会默认指向window。 - 子类继承修正:等子类完成原型继承后再保存父类的
step方法,重写时用oldStep.call(this)确保父类方法的this指向当前子类实例。
内容的提问来源于stack exchange,提问作者maximosis
相关产品推荐
相关产品推荐

