Protractor+JavaScript:HomePage继承BasePage失败及全局方法调用问题
你的问题出在只简单把HomePage的原型指向了BasePage的原型——这其实不是真正的继承,反而会让两个构造函数共享同一个原型对象,而且你没修正构造函数的指向,也没调用父类的构造函数,所以自然访问不到父类的方法。下面给你两种常用的正确继承方式,以及如何让BasePage的方法全局可用:
一、正确实现继承的两种方式
1. ES5 组合继承(最经典的传统方式)
这种方式既可以继承父类的原型方法,也能继承父类的实例属性,是ES5环境下最常用的继承方案:
// 先定义父类 BasePage function BasePage() { // 父类的实例属性 this.pageTitle = "基础页面"; } // 父类的原型方法 BasePage.prototype.render = function() { console.log("渲染基础页面结构"); }; // 定义子类 HomePage function HomePage() { // 调用父类构造函数,让子类实例继承父类的实例属性 BasePage.call(this); // 子类自己的实例属性 this.homeTitle = "首页"; } // 创建一个以 BasePage.prototype 为原型的新对象,赋值给子类原型 // 这样既继承了父类原型方法,又不会和父类原型共享同一个对象 HomePage.prototype = Object.create(BasePage.prototype); // 修正子类的 constructor 指向,否则它会指向 BasePage HomePage.prototype.constructor = HomePage; // 子类自己的原型方法 HomePage.prototype.showHomeBanner = function() { console.log("展示首页横幅"); }; // 测试 const homePage = new HomePage(); homePage.render(); // 可以正常调用父类的 render 方法 console.log(homePage.pageTitle); // 可以访问父类的实例属性 homePage.showHomeBanner(); // 子类自己的方法正常工作
2. ES6 Class 继承(更简洁直观)
如果你的项目环境支持ES6+,用class语法实现继承会更清晰易读:
class BasePage { constructor() { this.pageTitle = "基础页面"; } render() { console.log("渲染基础页面结构"); } } class HomePage extends BasePage { constructor() { // 必须先调用 super(),才能在子类构造函数中使用 this super(); this.homeTitle = "首页"; } showHomeBanner() { console.log("展示首页横幅"); } } // 测试 const homePage = new HomePage(); homePage.render(); // 正常调用父类方法 console.log(homePage.pageTitle); // 访问父类实例属性
二、让BasePage的方法在所有模块中全局可用
1. 浏览器环境
- 全局挂载方式:把BasePage挂载到
window对象上,这样所有脚本都能直接访问:// 定义完 BasePage 后,挂载到 window window.BasePage = BasePage; // 其他任意脚本中都可以直接使用 class HomePage extends window.BasePage { // ... } - 模块导入方式(推荐):用ES6模块规范导出/导入,避免全局命名冲突:
// basePage.js 文件 export class BasePage { /* ... */ } // homePage.js 文件 import { BasePage } from './basePage.js'; class HomePage extends BasePage { /* ... */ }
2. Node.js环境
- 全局挂载方式:把BasePage挂载到
global对象:// 定义完 BasePage 后 global.BasePage = BasePage; // 其他文件中直接使用 class HomePage extends BasePage { /* ... */ } - 模块导入方式(推荐):用CommonJS或ES6模块规范:
// basePage.js(CommonJS) module.exports = class BasePage { /* ... */ }; // homePage.js const BasePage = require('./basePage.js'); class HomePage extends BasePage { /* ... */ }
注意:全局变量虽然方便,但容易引发命名冲突,推荐优先使用模块导入导出的方式,代码更规范易维护。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

