- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我对所有扩展抽象类的子类使用依赖注入(inject)。
问题是在抽象构造函数类中我启动了一个我计划在其子类中覆盖的方法,如果有必要的话。
我遇到了一个问题,即我注入(inject)的依赖项在从 super 启动的覆盖类中不可见。
这是一个代码示例:
abstract class Base {
constructor(view: string) {
this._assemble();
}
protected _assemble(): void {
console.log("abstract assembling for all base classes");
}
}
class Example extends Base {
constructor(view: string, private helper: Function) {
super(view);
console.log(this.helper);
}
public tryMe(): void {
this._assemble();
}
protected _assemble(): void {
super._assemble();
// at first run this.helper will be undefined!
console.log("example assembling", this.helper);
}
}
let e = new Example("hoho", function () { return; })
console.log("So now i will try to reassemble...");
e.tryMe();
所以一个问题的核心是typescript将Example类转译成如下代码:
function Example(view, helper) {
_super.call(this, view);
this.helper = helper;
console.log(this.helper);
}
取而代之的是:
function Example(view, helper) {
this.helper = helper;
_super.call(this, view);
console.log(this.helper);
}
如您所见,如果我在 JavaScript 中将 this.helper
放在 _super
之前,this.helper
将始终在 中可见_组装
。即使 super
会调用 _assemble
函数。
但默认分配给它是在 _super
调用之后。所以如果 super
类将调用汇编。第一次在Example中重写的_assemble
方法中是不可见的。
所以我的问题是...
或
现在我解决了我的问题,只是从 super
类中删除 _assemble
,并始终从子类中调用它。但这只是感觉不对。
注意事项:这是编译后的 JavaScript 代码与固定的 JavaScript 代码演示:
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Base = (function () {
function Base(view) {
this._assemble();
}
Base.prototype._assemble = function () {
document.write("<p>abstract assembling for all base classes</p>");
};
return Base;
}());
var Example = (function (_super) {
__extends(Example, _super);
function Example(view, helper) {
_super.call(this, view);
this.helper = helper;
console.log(this.helper);
}
Example.prototype.tryMe = function () {
this._assemble();
};
Example.prototype._assemble = function () {
_super.prototype._assemble.call(this);
// at first run this.helper will be undefined!
document.write("<p>example assembling <b/>" + (this.helper) + "</b></p>");
};
return Example;
}(Base));
var e = new Example("test", function () { return "needle"; });
document.write("<p><i>So now i will try to reassemble...</i></p>");
e.tryMe();
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Base = (function () {
function Base(view) {
this._assemble();
}
Base.prototype._assemble = function () {
document.write("<p>abstract assembling for all base classes</p>");
};
return Base;
}());
var Example = (function (_super) {
__extends(Example, _super);
function Example(view, helper) {
/**
* Slight change, compiled assigning to this BEFORE _super.
*/
this.helper = helper;
_super.call(this, view);
console.log(this.helper);
}
Example.prototype.tryMe = function () {
this._assemble();
};
Example.prototype._assemble = function () {
_super.prototype._assemble.call(this);
// at first run this.helper will be undefined!
document.write("<p>example assembling <b/>" + (this.helper) + "</b></p>");
};
return Example;
}(Base));
var e = new Example("test", function () { return "Needle"; });
document.write("<p><i>So now i will try to reassemble...</i></p>");
e.tryMe();
最佳答案
在 Java 和其他 OOP 语言中,super() 必须在当前对象被实例化之前调用。
这是合乎逻辑的,因为 child cannot be born before parent
.
TypeScript 2 now can have statements before super
, if they are not using to this
.
这是为什么 this
的答案的一部分。不能在晚饭前使用。
问题涉及的下一部分是 parent
对象实际上调用了其子项的覆盖 assemble
在这个 child 根本没有被实例化的同时。
这看起来很奇怪,因为 child 没有被实例化,但是父构造函数调用了 child 的方法......而且看起来不自然,就像未出生的 child 说“爸爸”一样。
See similar post about this issue.
但这样想是错误的。将在构造函数中使用的子项的覆盖纯粹是为了改变您的子项的实例化方式。
在父构造函数中使用的方法覆盖必须告诉您的实例应该如何制作。从那些对父可用的资源,而不是从您不存在的实例所拥有的资源。
原型(prototype)中的继承通常通过将新原型(prototype)与 extend
组合来实现像这样的功能。
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
从这个 Angular 来看,没有“ child ”和“ parent ”本身,但有某种“集合”。只有当一个集合已经存在时,它才能被另一个集合扩展。这将我们带到:
Top-down and bottom-up design.
原型(prototype)和鸭子打字在自下而上的设计中工作。自上而下设计中的 OOP。
只是不要!通过学习和实现 OOP 思想的力量!如何成功:
Use static ,但请注意,此更改对于对象的所有实例都是相同的。
如果你只将它用于依赖注入(inject),这没问题
智能覆盖。
不要使用兄弟(“子”)实例的额外资源,并创建一个自己的额外方法,该方法将从构造函数中调用。
下面的示例(请注意,这并不违反 LSP,因为在构造函数中只设置了一次 __assembled
):
abstract class Base {
constructor(view: string) {
this._assemble();
}
protected _assemble(): void {
console.log("abstract assembling for all base classes");
}
}
class Example extends Base {
private __assembled: boolean = false;
constructor(view: string, private helper: Function) {
super(view);
this._assemble_helper();
this.__assembled = true;
}
public tryMe(): void {
this._assemble();
}
protected _assemble(): void {
super._assemble();
// removed from here all extra resources
// but run them when u need to assemble them again.
if (this.__assembled) {
this._assemble_helper();
}
}
protected _assemble_helper(): void {
// at first run this.helper will be undefined!
console.log("example assembling", this.helper);
}
}
let e = new Example("hoho", function () { return; })
console.log("So now i will try to reassemble...");
e.tryMe();
这是转译后的 ES5 结果:
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Base = (function () {
function Base(view) {
this._assemble();
}
Base.prototype._assemble = function () {
console.log("abstract assembling for all base classes");
};
return Base;
}());
var Example = (function (_super) {
__extends(Example, _super);
function Example(view, helper) {
var _this = _super.call(this, view) || this;
_this.helper = helper;
_this.__assembled = false;
_this._assemble_helper();
_this.__assembled = true;
return _this;
}
Example.prototype.tryMe = function () {
this._assemble();
};
Example.prototype._assemble = function () {
_super.prototype._assemble.call(this);
// removed from here all extra resources
// but run them when u need to assemble them again.
if (this.__assembled) {
this._assemble_helper();
}
};
Example.prototype._assemble_helper = function () {
// at first run this.helper will be undefined!
console.log("example assembling", this.helper);
};
return Example;
}(Base));
var e = new Example("hoho", function () { return; });
console.log("So now i will try to reassemble...");
e.tryMe();
关于javascript - 在 ES5 的转译输出中调用 `this` 之前,TypeScript 应该分配给 `_super` 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41020742/
在 ES6 中,我们可以使用 rest 参数,有效地创建一个参数数组。 TypeScript 使用 for 循环将其转换为 ES5。我想知道是否存在使用 for 循环方法比使用 Array.proto
鉴于以下情况: require('babel-core').transform('3').code 有没有办法让它返回3 (一个表达式)而不是 3; (一份声明)? 我试过了: 在网络和各种站点上搜索
这是我的计划。我想使用适用于 Windows 和 Mac 的 Typescript 构建应用程序。但是,由于我要将 Typeascript 代码转换为 Javascript 代码,所以我想尽可能实现一
是否有一个独立的转译器用于将 JSX 转换为 JavaScript(即只是 → createElement("foo", …) ,没有别的)? 我知道我可以只使用 Babel 和 Transform
我知道使用 babel 设置内联 javascript transpile // your es6 code 但是有没有可能将 es6 代码的字符串版本提供给 babel 并获得作为字
我想转译 ES6 中的几个 js 文件以与 chrome 兼容,但似乎 http://babeljs.io/docs/usage/cli/ 中的文档不准确。 完成前几个步骤后,我在控制台中输入:bab
我玩了一下 Babel 和 ES6,转译了一些代码,但我被困在这部分了: class App extends SomeParent { myFunction() { } } 我感兴趣的
我全新安装了 Next.js,并且希望能够使用 import 和 async/await 等。 我已经更新了我的 .babelrc { "plugins": [ [ "modu
我在 index.html 中有这个 SystemJS 配置: System.config({ defau
我正在开发一个网络应用程序,并将我的 Javascript 分成多个文件。我正在使用 Babel 将 ES2015 源文件目录转换为单个 ES5 文件。来自面向对象的背景,我喜欢拥有“类”,无论它们是
我对 Webpack 还很陌生,我只是想在这里启动一个简单的项目。我收到以下错误: ERROR in ./index.js Module parse failed: /Users/jay/Docume
我正在开发一个使用 es6 和 es7 代码的 Aurelia 应用程序,我正在尝试使用 babel 转译代码。我的 packages.json 文件中有以下内容 "scripts": { "
问题 当我使用npm run start运行nodemon时,我收到错误:找不到模块“Test”,以及当我使用npm run build构建文件时 并运行 ./dist/index.js,我得到同样的
由于 babel 没有正确转译代码,所有测试都失败了。 下面是来自控制台的错误。 Jest encountered an unexpected token This usually means t
我知道这样的事情不应该难倒我,但它确实难倒了我。 我正在学习如何使用 coffeescript 以及如何使用 Adobe Brackets 作为我的文本编辑器。那么如何在 Adobe Brac
TypeScript 在转译过程中检查整个代码库,即使实际上只有一个文件发生了变化。对于小型项目,这很好,但随着我们的代码库增长,这需要相当长的时间。 在开发过程中,我希望我的单元测试能够快速响应。单
我是第一次建立 TS 项目。我很好奇 - 我可以使用和配置 Babel 或者只是做 tsc .. 进行转译。 两者的主要区别是什么? 最佳答案 主要区别在于对 TypeScript 语言本身的支持。
对于我拥有的每个手动模拟,我都会收到来自 Jest 的警告,因为它同时找到了它的 .ts 和 .js 版本,并要求我删除一个,即: jest-haste-map: duplicate manual m
我是 babel 的新手,正在尝试转换我的 es6 代码以与 IE11 一起使用。但是当我在 IE11 中运行代码时,我收到关于我的 forEach 代码的 js 错误。根据我的阅读,我需要添加预设
尝试使用 mocha 对 ReactJS 应用程序进行单元测试,但在 node_modules 中使用的 es6 功能(导入/导出)中出现错误文件夹。有问题的应用程序是使用 babel 进行转译的,但
我是一名优秀的程序员,十分优秀!