It works fine as the following:
function A() {
}
A.prototype.f1 = function() {
alert('f1');
};
A.prototype.f2 = function() {
// calls f1
A.prototype.f1();
};
var a = new A();
a.f2(); // alert f1 correctly
But there's a function B to make A undefined to window scope, but can be accessed inside B scope:
function A() {
}
A.prototype.f1 = function() {
alert('f1');
};
A.prototype.f2 = function() {
// calls f1
A.prototype.f1();
};
function B() {
var PrivateA = null;
this.makePrivate = function() {
PrivateA = A; // private access
A = undefined; // undefined with window object
};
this.callA = function() {
var a = new PrivateA();
a.f2(); // it calls A.prototype.f1();, but A is undefined now
};
}
var b = new B();
// expect to accessible
var a = new A();
b.makePrivate();
// expect to inaccessible to window
alert(typeof A); // expect to be 'undefined'
b.callA(); // expect to alert 'f1', which not works now since A is undefined
I want make A accessible before B is called and A inaccessible when B is called.
Please give some advice.
You can set up B to look like this:
function B() {
var PrivateA; // It's not accessible from outside of B's scope
this.makePrivate = function() {
PrivateA = A; // Still in B's scope, so it works
A = undefined;
};
this.callA = function() {
var a = new PrivateA(); // So is this
a.f2();
};
}
Here's what happens when I run it:
> var b = new B();
> A
function A() {
this.f1 = function() {
alert('f1');
};
this.f2 = function() {
// calls f1
this.f1();
};
}
> b.makePrivate();
> A
undefined
> b.callA(); // I get an alert that says 'f1'
Related
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()
I was trying something different and ended up with these codes..
var f1 = function() {
this.x = 10;
this.innerf = function() { console.log(this.x); }
}
var of1 = new f1();
of1.innerf();
var f2 = function() {
return function() {
this.x = 10;
this.innerf = function() { console.log(this.x); }
}
}
var of2 = new f2();
of2.innerf();
It is throwing error ??! of2.inner is not a function
So, my anonymous function is returning same function body to my variable.
Why still i cannot able to instantiate??
The first part returns an object of which you can call the innerf method.
The second part returns a function that would return an object if you called it. But you don't.
This would work. Call the function f2(). It's return value is the anonymous function. Then, with new <return value of f2>(), you can create an instance of the object.
var f2 = function() {
return function() {
this.x = 10;
this.innerf = function() { console.log(this.x); }
}
}
var of2 = new (f2())();
of2.innerf();
// The two lines above can also be written as:
var of3constructor = f2(); // This returns the inner anonymous function.
var of3 = new of3constructor(); // This creates an instance by invoking the anonymous function.
of3.innerf();
Examples that work:
Creating it directly:
var f1 = function() {
this.x = 11;
this.innerf = function() {
console.log(this.x);
}
}
var of1 = new f1();
of1.innerf();
Returning a new object from a function:
var f2 = function() {
return new function() {
this.x = 12;
this.innerf = function() {
console.log(this.x);
}
}
}
var of2 = f2();
of2.innerf();
Returning an object:
var f3 = function() {
return {
x: 13,
innerf : function() {
console.log(this.x);
}
}
}
var of3 = f3();
of3.innerf();
Another one:
var f4 = function() {
return function() {
this.x = 10;
this.innerf = function() {
console.log(this.x);
}
}
}
var of4 = new (f2())();
of2.innerf();
Remember that when you call a function without the "new" keyword "this" points object where the functions was declared, in this case "window"
You need to return this from the inner function to the outer function. Also you need to run the inner function immediately.
jsFiddle:
http://jsfiddle.net/5dxybbb5/
var f1 = function() {
this.x = 10;
this.innerf = function() {console.log(this.x);}
}
var of1 = new f1();
of1.innerf();
var f2 = function() {
return function() {
this.x = 10;
this.innerf = function() {console.log(this.x);}
return this;
}();
}
var of2 = new f2();
of2.innerf();
Also this explains the () after a function declaration
What is the (function() { } )() construct in JavaScript?
I want to have a function A that accepts another function B as an argument, and then runs B as it were defined within the closure scope of A, i.e. has access to all the local variables.
For example, simplistically:
var A = function(B){
var localC = "hi";
B();
}
var B = function(){
console.log(localC);
}
A(B); // to log 'hi'
The only way I have found is to use eval. Does ec6 give any better options maybe?
One solution is to pass localC as argument in function B:
var A = function(B) {
var localC = "hi";
B(localC);
}
var B = function(localC) {
console.log(localC);
}
A(B); // outputs hi
Alternative using arguments:
var A = function(B) {
var localC = "hi";
B(localC, "test");
}
var B = function() {
var i = 0;
for (i; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
A(B); // outputs hi, test
You can make the context explicit and pass it to B:
var A = function(B){
var context = {
localC: "hi"
};
B(context);
}
var B = function(context){
console.log(context.localC);
}
A(B); // hi
You can also use this with new and prototype:
var A = function() {
this.localC = "hi";
}
A.prototype.b = function(context){
console.log(this.localC);
}
var a = new A();
a.b(); // hi
or without the prototype:
var A = function() {
this.localC = "hi";
}
var a = new A();
a.b = function(context){
console.log(this.localC);
};
a.b(); // hi
You can use this with bind:
var a = {
localC: "hi"
};
function B(foo) {
console.log(this.localC, foo);
}
B.bind(a)("foo"); // hi foo
// .call:
B.call(a, "foo"); // hi foo
bind sets the context for this. call takes the context as it's first argument.
This one is not good:
var A = function(B){
var localC = "hi";
B.bind(this)(); // this is the global object, you need `new` to create a new scope
}
var B = function(){
console.log(this.localC);
}
A(B); // undefined
var A = function(B){
var self = this;
self.localC = "hi";
self.localD = "hello";
B();
};
var B = function(){
var self=this;
alert(self.localD);
}
A(B); // to log 'hi'
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');
};
How can I inherit an objects variables within namespace(scope)?
var f2 = {
a: 'test'
}
f2.history = {
load: function(){ alert(this.a); }
}
// Turns out Undefined
f2.history.load();
There is no link between f2.history and f2. More generally there is no link between a property value and its holder.
You could call it like this :
f2.history.load.call(f2);
Or you could declare your objects with a factory :
var f2 = (function(){
var self = {
a: 'test'
};
self.history = {
load: function(){ alert(self.a); }
};
return self;
})();
This would allow
f2.history.load();
Another variant would let you define the submodules in a more separated way :
var f2 = {
a: 'test'
};
(function(f){
f.history = {
load: function(){ alert(f.a); }
}
})(f2);
The advantage of this last construct is that it's easy to declare sub-modules in different files.
use the namespace, f2, not this.
load: function(){ alert(f2.a); }
works
var f2 = {
a : 'test',
init: function(a) {
if (a) this.a = a; //set a, if a is defined
},
};
function history(a) {
function F() {};
F.prototype = f2;
var f = new F();
f.init(a);
load = function() {
alert(f.a);
}
return this;
}
var h1 = history();
h1.load(); //alerts "test"
var h2 = history('history');
h2.load(); //alerts "history"
//but now h1 also holds history
h1.load();