这是指 class 它是其中的一部分,而不是从中调用实例的那个
this is referring to the class which it is part of and not the one from which the instance is called
class ElPush {
pushElement(type) {
document
.querySelector(`#${type}-projects`)
.querySelectorAll("li")
.forEach((el) => {
this.itemLog.push(el);
});
}
}
我想使用 class ElPush 将元素推送到下面给出的 class ActiveItem 中存在的 itemLog 数组
class ActiveItem {
constructor() {
this.itemLog = [];
const elPush = new ElPush();
elPush.pushElement("active");
console.log(this.itemLog);
}
}
class FinishedItem {
constructor() {
this.itemLog = [];
const elPush = new ElPush();
elPush.pushElement("finished");
console.log(this.itemLog);
}
}
class App {
static init() {
const activeList = new ActiveItem();
}
}
App.init();
ElPush 中的这一 this.itemLog.push(el);
行抛出错误 Cannot read property 'push' of undefined
我知道这不是一个实用的解决方案,但我只是在练习 opp 概念,真的很想提供任何解决方案
// - still class based for being recognizable to the OP.
// - the query part should be refactored
// as simple helper/utility function.
//
class ProjectItemQuery {
query(type) {
return Array.from(document
.querySelector(`#${ type }-projects`)
.querySelectorAll("li")
);
}
}
// refactored query helper.
function queryProjectItems(type) {
return Array.from(document
.querySelector(`#${ type }-projects`)
.querySelectorAll("li")
);
}
class ActiveItems {
constructor() {
const itemQuery = new ProjectItemQuery;
this.list = itemQuery.query("active");
//this.list = queryProjectItems("active");
console.log('ActiveItems :: list : ', this.list);
}
}
class FinishedItems {
constructor() {
this.list = queryProjectItems("finished");
console.log('FinishedItems :: list : ', this.list);
}
}
class App {
static init() {
const activeItemList = (new ActiveItems).list;
const finishedItemList = (new FinishedItems).list;
console.log('App :: init :: activeItemList : ', activeItemList);
console.log('App :: init :: finishedItemList : ', finishedItemList);
}
}
App.init();
.as-console-wrapper { min-height: 100%!important; top: 0; }
<ul id='active-projects'>
<li>foo</li>
<li>bar</li>
</ul>
<ul id='finished-projects'>
<li>baz</li>
<li>biz</li>
</ul>
编辑
Q
- abhinay khalatkar
i went with this return approach already but what I wanted to know is, if the above-given way will work or not?i mean is it possible to change the property of class (a) from a different class(b) using "bind()" and "this" if class (b) is instantiated in this class(a) ? I don't want a workaround but a straightforward way to do this.if not I will go with this way. Thank you for the A2A.
A
- 彼得塞利格
Of course one can .. there are even many ways of achieving this task. But why does one want to add more complexity (here ... less good to read, easier to screw up with thus more error prone) to one's design instead of keeping it clean and lightweight?
将上面给出的示例代码与接下来提供的示例代码进行比较。前者发生的事情比现在发生的事情更具可读性/清晰性/可理解性......
// - a less favourable, function based, mixin approach
//
function ProjectItemQueryMixin() {
if (!Array.isArray(this.list)) {
this.list = [];
}
this.queryAndPush = function (type) {
document
.querySelector(`#${ type }-projects`)
.querySelectorAll("li")
.forEach(elm => this.list.push(elm));
}
}
class ActiveItems {
constructor() {
// this.list = [];
// - Applying the mixin based `query`
// method directly to an instance
// is the less favourable way.
ProjectItemQueryMixin.call(this);
this.queryAndPush("active");
console.log('ActiveItems :: list : ', this.list);
}
}
class FinishedItems {
constructor() {
// this.list = [];
this.queryAndPush("finished");
console.log('FinishedItems :: list : ', this.list);
}
}
ProjectItemQueryMixin.call(FinishedItems.prototype);
// - Applying the mixin based `query` method to the
// prototype was the choice for everyone that is
// concerned about design and memory usage.
// - A lot of developers will find this confusing as well.
class App {
static init() {
const activeItemList = (new ActiveItems).list;
const finishedItemList = (new FinishedItems).list;
console.log('App :: init :: activeItemList : ', activeItemList);
console.log('App :: init :: finishedItemList : ', finishedItemList);
}
}
App.init();
.as-console-wrapper { min-height: 100%!important; top: 0; }
<ul id='active-projects'>
<li>foo</li>
<li>bar</li>
</ul>
<ul id='finished-projects'>
<li>baz</li>
<li>biz</li>
</ul>
第三次迭代,这次尽可能接近OP的代码
// ... Again, one does not need a class instance for this task.
//
// A simple function/method with `this` context called
// `queryAndPushProjectItems(type)` would already solve
// the OP's problem.
//
class ProjectItemQuery {
queryAndPush(type) {
document
.querySelector(`#${ type }-projects`)
.querySelectorAll("li")
.forEach(elm => this.list.push(elm));
}
}
class ProjectItems {
// - The constructor's `type` argument prevents
// copying over and over the same item class
// related code that just differs in how items
// are going to be queried.
constructor(type) {
this.list = [];
const itemQuery = new ProjectItemQuery;
// - This code block answers th OP's question.
// - Call `queryAndPush` of the above created
// `ProjectItemQuery` instance within the
// `this` context of any `ProjectItems`
// instance.
// - Of course this is not a desirable design.
itemQuery.queryAndPush.call(this, type);
// - or ...
// `queryAndPushProjectItems.call(this, type);`
console.log('ProjectItems :: type, list : ', type, this.list);
}
}
class App {
static init() {
const activeItems = new ProjectItems('active');
const finishedItems = new ProjectItems('finished');
console.log('App :: init :: activeItems.list : ', activeItems.list);
console.log('App :: init :: finishedItems.list : ', finishedItems.list);
}
}
App.init();
.as-console-wrapper { min-height: 100%!important; top: 0; }
<ul id='active-projects'>
<li>foo</li>
<li>bar</li>
</ul>
<ul id='finished-projects'>
<li>baz</li>
<li>biz</li>
</ul>
class ElPush {
pushElement(type) {
document
.querySelector(`#${type}-projects`)
.querySelectorAll("li")
.forEach((el) => {
this.itemLog.push(el);
});
}
}
我想使用 class ElPush 将元素推送到下面给出的 class ActiveItem 中存在的 itemLog 数组
class ActiveItem {
constructor() {
this.itemLog = [];
const elPush = new ElPush();
elPush.pushElement("active");
console.log(this.itemLog);
}
}
class FinishedItem {
constructor() {
this.itemLog = [];
const elPush = new ElPush();
elPush.pushElement("finished");
console.log(this.itemLog);
}
}
class App {
static init() {
const activeList = new ActiveItem();
}
}
App.init();
ElPush 中的这一 this.itemLog.push(el);
行抛出错误 Cannot read property 'push' of undefined
我知道这不是一个实用的解决方案,但我只是在练习 opp 概念,真的很想提供任何解决方案
// - still class based for being recognizable to the OP.
// - the query part should be refactored
// as simple helper/utility function.
//
class ProjectItemQuery {
query(type) {
return Array.from(document
.querySelector(`#${ type }-projects`)
.querySelectorAll("li")
);
}
}
// refactored query helper.
function queryProjectItems(type) {
return Array.from(document
.querySelector(`#${ type }-projects`)
.querySelectorAll("li")
);
}
class ActiveItems {
constructor() {
const itemQuery = new ProjectItemQuery;
this.list = itemQuery.query("active");
//this.list = queryProjectItems("active");
console.log('ActiveItems :: list : ', this.list);
}
}
class FinishedItems {
constructor() {
this.list = queryProjectItems("finished");
console.log('FinishedItems :: list : ', this.list);
}
}
class App {
static init() {
const activeItemList = (new ActiveItems).list;
const finishedItemList = (new FinishedItems).list;
console.log('App :: init :: activeItemList : ', activeItemList);
console.log('App :: init :: finishedItemList : ', finishedItemList);
}
}
App.init();
.as-console-wrapper { min-height: 100%!important; top: 0; }
<ul id='active-projects'>
<li>foo</li>
<li>bar</li>
</ul>
<ul id='finished-projects'>
<li>baz</li>
<li>biz</li>
</ul>
编辑
Q
- abhinay khalatkar
i went with this return approach already but what I wanted to know is, if the above-given way will work or not?i mean is it possible to change the property of class (a) from a different class(b) using "bind()" and "this" if class (b) is instantiated in this class(a) ? I don't want a workaround but a straightforward way to do this.if not I will go with this way. Thank you for the A2A.
A
- 彼得塞利格
Of course one can .. there are even many ways of achieving this task. But why does one want to add more complexity (here ... less good to read, easier to screw up with thus more error prone) to one's design instead of keeping it clean and lightweight?
将上面给出的示例代码与接下来提供的示例代码进行比较。前者发生的事情比现在发生的事情更具可读性/清晰性/可理解性......
// - a less favourable, function based, mixin approach
//
function ProjectItemQueryMixin() {
if (!Array.isArray(this.list)) {
this.list = [];
}
this.queryAndPush = function (type) {
document
.querySelector(`#${ type }-projects`)
.querySelectorAll("li")
.forEach(elm => this.list.push(elm));
}
}
class ActiveItems {
constructor() {
// this.list = [];
// - Applying the mixin based `query`
// method directly to an instance
// is the less favourable way.
ProjectItemQueryMixin.call(this);
this.queryAndPush("active");
console.log('ActiveItems :: list : ', this.list);
}
}
class FinishedItems {
constructor() {
// this.list = [];
this.queryAndPush("finished");
console.log('FinishedItems :: list : ', this.list);
}
}
ProjectItemQueryMixin.call(FinishedItems.prototype);
// - Applying the mixin based `query` method to the
// prototype was the choice for everyone that is
// concerned about design and memory usage.
// - A lot of developers will find this confusing as well.
class App {
static init() {
const activeItemList = (new ActiveItems).list;
const finishedItemList = (new FinishedItems).list;
console.log('App :: init :: activeItemList : ', activeItemList);
console.log('App :: init :: finishedItemList : ', finishedItemList);
}
}
App.init();
.as-console-wrapper { min-height: 100%!important; top: 0; }
<ul id='active-projects'>
<li>foo</li>
<li>bar</li>
</ul>
<ul id='finished-projects'>
<li>baz</li>
<li>biz</li>
</ul>
第三次迭代,这次尽可能接近OP的代码
// ... Again, one does not need a class instance for this task.
//
// A simple function/method with `this` context called
// `queryAndPushProjectItems(type)` would already solve
// the OP's problem.
//
class ProjectItemQuery {
queryAndPush(type) {
document
.querySelector(`#${ type }-projects`)
.querySelectorAll("li")
.forEach(elm => this.list.push(elm));
}
}
class ProjectItems {
// - The constructor's `type` argument prevents
// copying over and over the same item class
// related code that just differs in how items
// are going to be queried.
constructor(type) {
this.list = [];
const itemQuery = new ProjectItemQuery;
// - This code block answers th OP's question.
// - Call `queryAndPush` of the above created
// `ProjectItemQuery` instance within the
// `this` context of any `ProjectItems`
// instance.
// - Of course this is not a desirable design.
itemQuery.queryAndPush.call(this, type);
// - or ...
// `queryAndPushProjectItems.call(this, type);`
console.log('ProjectItems :: type, list : ', type, this.list);
}
}
class App {
static init() {
const activeItems = new ProjectItems('active');
const finishedItems = new ProjectItems('finished');
console.log('App :: init :: activeItems.list : ', activeItems.list);
console.log('App :: init :: finishedItems.list : ', finishedItems.list);
}
}
App.init();
.as-console-wrapper { min-height: 100%!important; top: 0; }
<ul id='active-projects'>
<li>foo</li>
<li>bar</li>
</ul>
<ul id='finished-projects'>
<li>baz</li>
<li>biz</li>
</ul>