I am a c++ programmer, Here is a C++ code, how to have similar JS code,
class A {
public:
void sayHello();
};
class B {
public:
A a;
};
main()
{
B b;
b.a.sayHello();
}
// Define class A
function A() {}
A.prototype.sayHello = function() { alert('hello!'); };
// Define class B
function B() { this.a = new A(); }
// Use them
var b = new B();
b.a.sayHello();
The most basic and simplest example:
function A() {
return {
sayHello: function() {
}
}
}
function B() {
return {
a: new A()
}
}
var b = new B();
b.a.sayHello();
Related
I need to create a function in JS that gets all the methods from the whole inheritance tree so as to insert one <button> for each method. I have this code
function A () {
}
A.prototype.a = function () {
console.log('a');
}
function B () {
this.super = A;
this.super();
}
B.prototype = new A;
B.prototype.constructor = B;
B.prototype.b = function () {
console.log('b');
}
function C () {
this.super = B;
this.super();
}
C.prototype = new B;
C.prototype.constructor = C;
C.prototype.c = function () {
console.log('c');
}
function D () {
}
D.prototype = C;
D.prototype.constructor = D;
D.prototype.d = function () {
console.log('d');
}
const dd = new D();
I need some way to find the methods of the whole tree in case I didn't know how many ancestors an object has. For example: If an object C had A and B as its ancestors, I need the methods from A, B, and C; If a D object were a child of A-B-C, I need the methods of them four (A, B, C, and D). I may be able to trace by hand each method so as to write a code that does that for me, buy I need it to be dynamic.
This is what I'm using:
console.log(Object.getOwnPropertyNames(dd.__proto__).filter(function (property) {
return (
typeof dd.__proto__[property] === 'function' && property !== 'constructor'
);
}))
There is a mistake in your setup-code:
Change:
D.prototype = C;
to:
D.prototype = new C;
Then to get the list of methods (even when not enumerable), make a recursive call. You can even make it a generator.
To make clear where the methods come from, I have prefixed them with the name of the prototype object (like A.prototype). You will see that when functions with the same name exist at multiple levels of the prototype chain, they get each listed:
function * iterMethods(o) {
if (!o || o === Object.prototype) return;
for (let name of Object.getOwnPropertyNames(o)) {
try {
if (name !== "constructor" && typeof o[name] === "function") {
yield o.constructor.name + ".prototype." + name;
}
} catch {}
}
yield * iterMethods(Object.getPrototypeOf(o));
}
// Your code:
function A () {
}
A.prototype.a = function () {
console.log('a');
}
function B () {
this.super = A;
this.super();
}
B.prototype = new A;
B.prototype.constructor = B;
B.prototype.b = function () {
console.log('b');
}
function C () {
this.super = B;
this.super();
}
C.prototype = new B;
C.prototype.constructor = C;
C.prototype.c = function () {
console.log('c');
}
function D () {
}
D.prototype = new C;
D.prototype.constructor = D;
D.prototype.d = function () {
console.log('d');
}
const dd = new D();
// The call:
console.log(Array.from(iterMethods(Object.getPrototypeOf(dd))));
It is easier to set up this prototypal hierarchy when you use the class ... extends syntax. I would also not define super as that is a keyword that is natively available. Here is how that would look:
function * iterMethods(o) {
if (!o || o === Object.prototype) return;
for (let name of Object.getOwnPropertyNames(o)) {
try {
if (name !== "constructor" && typeof o[name] === "function") {
yield o.constructor.name + ".prototype." + name;
}
} catch {}
}
yield * iterMethods(Object.getPrototypeOf(o));
}
// class syntax version:
class A {
a() {
console.log('a');
}
}
class B extends A {
b() {
console.log('b');
}
}
class C extends B {
c() {
console.log('c');
}
}
class D extends C {
d() {
console.log('d');
}
}
const dd = new D();
// The call:
console.log(Array.from(iterMethods(Object.getPrototypeOf(dd))));
All methods inside a class a will call a method b,How to call c() or d() automatically calls b() without writing b() in c() or d()
class a {
b() {}
c() {
b();
console.log("123")
}
d() {
b();
console.log("123")
}
}
You can do this by returning a proxy from a's constructor that intercepts name lookups and tests whether they are functions. If they are, call b (unless you actually called b):
class a {
constructor(){
const handler = {
get(target, propKey, receiver) {
const targetValue = Reflect.get(target, propKey, receiver);
if (typeof targetValue === 'function') {
return function (...args) {
// don't recursively call b
if (propKey !=='b') target.b()
return targetValue.apply(this, args); // call original function
}
} else {
return targetValue;
}
}
};
return new Proxy(this, handler);
}
b(){
console.log('b called')
}
c(arg){
console.log("c called with ", arg)
}
d(){
console.log("d called")
}
}
let instance = new a
instance.c("hello")
instance.d()
instance.b() // only called once
// still works for methods set after the fact:
a.prototype.g = function(){
console.log("g called")
}
instance.g() // still calls b
You could traverse the .prototype property of a, and overwrite each method with one that first calls b.
class a {
b() { console.log("called b") }
c() {
console.log("called c")
}
d() {
console.log("called d")
}
}
for (const n of Object.getOwnPropertyNames(a.prototype)) {
const f = a.prototype[n];
if (typeof f === "function" && n !== "b") {
a.prototype[n] = function(...args) {
this.b();
return f.apply(this, args);
}
}
}
var aa = new a();
aa.c();
aa.d();
Suppose there are 2 functions A() and B():
var A = function() {
this.name = 'test'
}
A.prototype.showName() = {
console.log(this.name)
}
var B = function() {
this.age = 10
}
B.prototype.showAge() = {
console.log(this.age)
}
var a = new A();
var b = new B();
what I require is the instance of B() should inherit from instance of A()
Note: instance of B() should still have a function showAge()
class A {
f1() {
f2();
}
f2() {}
}
var a = new A();
console.log(a.f1());
returns f2 is not defined.
Whereas:
{
function f1() {
return f2();
}
function f2() {
return 'f2';
}
console.log(f1());
}
prints 'f2'
I'm just wondering why functions within classes are not hoisted?
class A {
f1() {
return f2()
}
f2() {
return 'f2'
}
}
var a = new A()
console.log(a.f1())
is not equivalent to
{
function f1() {
return f2()
}
function f2() {
return 'f2'
}
console.log(f1())
}
Instead, it is syntactic sugar for:
function A() {
}
A.prototype.f1 = function () {
return f2()
}
A.prototype.f2 = function () {
return 'f2'
}
var a = new A()
console.log(a.f1())
In this form, it should be more clear why referencing f2 fails: there is no f2 function in scope. Because the functions are set on the prototype, you'll need to access them using this:
class A {
f1() {
return this.f2()
}
f2() {
return 'f2'
}
}
var a = new A()
console.log(a.f1())
function a() {
this.a = function () {
console.log("In A");
}
this.b = function () {
console.log("In B");
}
this.c = function (cb) {
console.log("In C ");
}
this.d = function (cb) {
cb();
console.log("In D");
}
this.d(function () {
this.a();
this.b();
this.c();
});
}
var A = a();
IN A
IN B
IN C
IN D
var A = new a();
IN A
IN B
IN C
IN D
IN B
IN C
IN D
Could anyone explain me how this works?
Also, any suggestions on links where I can find such interesting problems/questions?
Thanks, in advance :)