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())
Related
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();
So I have 3 functions.
What i want to achieve is to take value from one function which is nested in parent function, and the pass it as the argument in third function.
And can this be achieved with closer, and how ?
Thanks so much.
function foo () {
var rand = 10;
function bar() {
return {
age:rand;
}
}
}
function addValue(arg) {
console.log(bar());
}
Call as below
function foo () {
var rand = 10;
return function bar() {
return {
age:rand
}
}();
}
function addValue(arg) {
console.log(foo());
}
Edited
function foo (func) {
var rand = 10;
function bar() {
return {
age:rand
}
};
//Do your stuff
return eval(func+"()");
}
function addValue(arg) {
console.log(foo("bar"));
}
You can instead assign the function to the parent object and call it like this.
function foo(){
var rand = 10;
this.bar = function(){
return {age: rand};
}
}
var obj = new foo();
function addVal() {
console.log(obj.bar());
}
addVal();
I have following javascript code
function MyFunc () {
var add = function () {
return "Hello from add";
};
var div = function () {
return "Hello from div";
};
var funcCall = function (obj) {
if (!obj) {
throw new Error("no Objects are passed");
}
return obj.fName();
};
return {
func: function (obj) {
funcCall(obj);
}
};
}
var lol = new MyFunc();
When lol.func({fName: add}); is passed it should invoke the function private function add or when lol.func({fName: div}); is passed it should invoke the private div function. What i have tried does not work. How can i achieve this.
DEMO
In this case it's better to store your inner function in the object so you can easily access this with variable name. So if you define a function "map"
var methods = {
add: add,
div: div
};
you will be able to call it with methods[obj.fName]();.
Full code:
function MyFunc() {
var add = function () {
return "Hello from add";
};
var div = function () {
return "Hello from div";
};
var methods = {
add: add,
div: div
};
var funcCall = function (obj) {
if (!obj) {
throw new Error("no Objects are passed");
}
return methods[obj.fName]();
};
return {
func: function (obj) {
return funcCall(obj);
}
};
}
var lol = new MyFunc();
console.log( lol.func({fName: 'add'}) );
When you pass lol.func({fName: add}) add is resolved in the scope of evaluating this code, not in the scope of MyFunc. You have to either define it in that scope like:
function MyFunc () {
var add = function () {
return "Hello from add";
};
var div = function () {
return "Hello from div";
};
var funcCall = function (obj) {
if (!obj) {
throw new Error("no Objects are passed");
}
return obj.fName();
};
return {
add: add,
div: div,
func: function (obj) {
funcCall(obj);
}
};
}
var lol = new MyFunc();
lol.func({fName: lol.add});
Or use eval.
please help to run a function that is in a different scope
have the following code:
function a(){
var rrr = 8;
function aim(arg){
console.log('aim' + arg);
console.log(rrr);
}
};
function b(){
a.aim('this is argument');
};
call a.aim ('this is argument'); does not work, the console displays a message
Uncaught ReferenceError: a is not defined
tried to call through apply. also unsuccessfully
using revealing module pattern:
var a = function(){
var rrr = 8;
function aim(arg){
console.log('aim' + arg);
console.log(rrr);
}
return {
aim: aim
}
}();
function b() {
a.aim('test');
}
function a(){
var rrr = 8;
return function aim(arg){
console.log('aim' + arg);
console.log(rrr);
}
};
function b(){
var aim = a();
aim('this is argument');
};
If you want to refer to a function as an object you need to create it first. Also, aim should be a property of this function (class)
function a() {
var rrr = 8;
this.aim = function(arg) {
console.log('aim' + arg);
console.log(rrr);
}
};
function b() {
var aa = new a();
aa.aim('this is argument');
}
You need the 2 minor changes:
function a(){
var rrr = 8;
this.aim = function(arg){
console.log('aim' + arg);
console.log(rrr);
}
};
var aa = new a();
function b(){
aa.aim('this is argument');
};
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();