I dont understand why/ how to accomplish this fairly simple thing. If someone could explain it that would be great.
function Module(config) {
this.host = {Collapse: $('C')};
function EnableCollapse() {
//I need to access host.Collapse here
this.host.Collapse.hide(); // Throws error
host.Collapse.hide(); //Throws error
}
}
How do I access Collapse inside this function? Or should these work and perhaps i have something else wrong?
function Module(config) {
var that = this;
that.host = {Collapse: $('C')};
function EnableCollapse() {
//I need to access host.Collapse here
that.host.Collapse.hide(); // Throws error
}
}
Assuming you're calling Module as a constructor, you could make EnableCollapse a property of the object rendered.
function Module(config) {
this.host = {
Collapse: $('C')
};
this.EnableCollapse = function () {
this.host.Collapse.hide();
}
}
var mod = new Module({...});
mod.EnableCollapse();
Otherwise, if you intend to keep EnableCollapse private, you manually set its this value.
function Module(config) {
this.host = {
Collapse: $('C')
};
function EnableCollapse() {
this.host.Collapse.hide();
}
EnableCollapse.call(this);
}
Ultimately, the value of this will depend on how you're calling Module and Collapse.
You access Collapse inside the function via this.host.Collapse
Related
In the past, if I want to hide a variable function, I can using IIFE
(function(){
var _hiddenVariable = "_hiddenVariable";
function _hiddenFunction(){
//blablabla
}
})();
console.log(_hiddenVariable); //error
_hiddenFunction(); //error
After ES6, I can use let and block scope to hide a variable, but function can't.
{
let _hiddenVariable = "_hiddenVariable";
function _hiddenFunction(){
//blablabla
}
}
console.log(_hiddenVariable); //error
_hiddenFunction(); //pass
Below is the only solution I can find.
{
let _hiddenFunction = function(){
//blablabla
}
}
_hiddenFunction(); //error
So, two questions.
Is there another way to hide a function in block scope?
Is it a good idea that I use the solution above in all my projects? If not, can you suggest me a solution better than this?
thx
Well, you can hide the function by returning only what you want from an object.
Some
class Character {
constructor (name, weapon){
this.name=name;
this.weapon=weapon;
}
attack = function(){
var that=this;
that.varToSee=54
const age=()=>{
return that.varToSee
}
that.receivedFunc=function (){
return "Attack";
}
return {
age: age
}
}
}
const shrek=new Character("Shrek", "cloth")
const receive =shrek.attack()
console.log(receive.age())
console.log(receive.receivedFunc())
You might see that receivedFunc will not be accessible.
I am working on a script and everythink worked fine, until a few days ago. I have an object, created with function(), where I work with several methods.
To access properties inside the object, I use the this keyword and that works fine.
As example:
var SeralCore = SeralCore || function ()
{
this.initSeral();
return this;
};
SeralCore.prototype = {
page = null;
initSeral = function ()
{
alert(this.page);
}
}
Full code: http://pastebin.com/81Zn9276
jsFiddle example: https://jsfiddle.net/g2ahu6ob/10/
When I have an event, where a callback is fired and I have to access the property page, I used the following, because I can't use this anymore:
$('.button').click(function () {
SeralCore.page = 'Some value';
});
This worked well, but suddenly there is an error saying I cannot reach an property (or object, in my case*) used like in the exameple above. The output is undefined.
I decided to investigate what the output would be if I log SeralCore. Surprisingly, it says the following:
As you can see, there is a < at the end of SeralCore, which doesn't belong there.
Is this normal? And is this the cause of not being able to access properties using the "full name" (SeralCore.page)? If so, is there a way to fix it?
Many, many thanks in advance because I can't figure out what I am doing wrong.
Snippet:
var SeralCore = SeralCore || function () {
this.initSeral();
return this;
};
window.onload = function () {
this.SeralCore = new SeralCore();
};
SeralCore.prototype = {
page: 'Page',
initSeral: function ()
{
this.registerPage.start();
},
registerPage: {
start: function ()
{
$('.output').text(typeof SeralCore.page + ' (Should show \'String\' when it can read SeralCore.page)');
}
}
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<span class="output"></span>
This is my code:
SLVD.promise = function() {
delete this.data;
delete this.callBack;
delete this.babyPromise;
};
SLVD.promise.prototype.then = function(callBack) {
if(this.data) {
return callBack(this.data);
}
else {
this.callBack = callBack;
this.babyPromise = new SLVD.promise();
return this.babyPromise;
}
};
SLVD.promise.prototype.resolve = function(data) {
if(this.callBack) {
var tPromise = this.callBack(data);
if(this.babyPromise) {
if(!(tPromise instanceof SLVD.promise)) {
this.babyPromise.resolve(tPromise);
}
else if(tPromise.data) {
this.babyPromise.resolve(tPromise.data);
}
else {
tPromise.callBack = this.babyPromise.callBack;
if(this.babyPromise.babyPromise) {
tPromise.babyPromise = this.babyPromise.babyPromise;
}
}
}
}
else {
this.data = data;
}
};
SLVD.promise.as = function(data) {
var promise = new SLVD.promise();
promise.resolve(data);
return promise;
};
It's a promise system. (Yes, I am aware there are already promise systems out there. Please don't bug me on that.) However, when the constructor is run, the member callBack is already set to "onThen(value)." And when I try deleting it in the constructor as below, it still does it. Does anyone know anything about this?
Other potentially helpful information:
The call to the constructor is new SLVD.promise();
I gave the entirety of the class definition. There is no inheritance, and I have no other hidden prototype properties.
I have done a search in files in notepad++ for onThen; I definitely have never used that name.
I am running this in Firefox.
I tried renaming callBack to weird things in case it was a reserved word of sorts, but it didn't help.
This image shows the code paused in the debugger on the line after I call delete in the constructor...
EDIT: For that matter, this.babyPromise is also predefined...(even after the delete). Why?
As I stated in the comments, the issue turned out to be some issue with Firebug (v 2.0.11). I switched over to using Chrome and its debugger, and I haven't had any problems like this since then.
I am trying to fix a function I have here to be able to use it without using a that = this (or self = this as some like to use). It is a scoping issue but I am not sure how to get around it, and I would like to get in the habit of not using a that = this . So the functions are all in a return (angular factory) and I am having trouble referencing another function . Let me show you what I mean :
return {
loadStates: function() {
var that = this;
//chgeck if is loaded module, then change and fire callback
var currentModules = moduleHolder.getModules();
if (currentModules[name]) {
//works here
this.prepState();
} else {
//module cannot be found check for 5 seconds
$log.warn("Requesting " + name + "...");
var timeToCheck = true;
setTimeout(function() {
timeToCheck = false;
}, 5000);
var check = {
init: function() {
check.checkAgain();
},
checkAgain: function() {
if (timeToCheck) {
if (currentModules[name]) {
//but not here
that.prepState();
} else {
//still doesn't exists
setTimeout(check.checkAgain, 200);
}
} else {
//doesn't exist after 5 seconds
$log.error("Requested module (" + name + ") could not be found at this time.");
}
}
};
check.init();
}
},
prepState: function() {
}
}
So in the top if it finds the currentModule[name] I can use a this.prepState() and it works fine. However inside the timing functions I cannot use the this anything because it is inside a different scope so I have temporarily gotten around this by setting a that = this up top, however I would like see if I could not use this method. How does one get around this without using the that= this? Thanks!
It is a scoping issue...
No, it isn't. this and scope have essentially nothing to do with each other. (For now; ES6's arrow functions will change that.) It's an issue of how the functions are called.
If you pass a function reference to something that will call it later, unless the thing you're passing it to has a way you can use to tell it what to use for this when calling it, your function will get called with this not referring to what you want it to refer to.
You can get a new function reference that will call your original function with the correct this by using Function#bind:
var usesCorrectThis = originalFunction.bind(valueForThis);
So for example, suppose I have:
var check = {
name: "Fred",
sayHello: function() {
console.log("Hi, I'm " + this.name);
}
};
If I do:
check.sayHello();
All is good: Calling the function as part of an expression retrieving it from a property tells the JavaScript engine to use the object as this during the call.
However, if I do:
setTimeout(check.sayHello, 0);
...that doesn't work right, because when setTimeout calls the function, it doesn't use the right value for this.
So I can use Function#bind to address that:
setTimeout(check.sayHello.bind(check), 0);
More (on my blog):
Mythical methods
You must remember this
there are different ways you can do that.
One way is to use bind function.you can use
var checkInitBindFn = check.init.bind(this);
checkInitBindFn();
Secondly you can use call and apply also.
check.init.call(this);
check.init.apply(this);
Like this you can use this instead of that.
Check the complete api doc online...
It's not a scoping issue. If you want to avoid self = this you can always reference functions by objects. Makes cleaner code and since factories in angular are singletons you're not wasting memory.
angular.module('myApp').factory('myFactory', function ($timeout) {
var myFactory = {
loadState: function () {
$timeout(function () {
myFactory.check();
}, 500);
},
check: function () {
},
};
return myFactory;
});
So here's the object 'playerTurnObj'
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
function setTurn(turnToSet) {
this.playerTurn=turnToSet;
}
function getTurn() {
return this.playerTurn;
}
}
and here is what I'm doing with it
var turn = new playerTurnObj();
turn.setTurn(1);
so I try to make the script do the setTurn() method in playerTurnObj() to save a 'turn' in a game I'm making. The problem is, it does not do the turn.setTurn(1); part because I keep getting the error above
what am I doing wrong? I searched, but I could not find an exact answer to my question.
This is not the way JavaScript works. Your "constructor" function contains inline functions that are not visible outside of the scope of playerTurnObj. So your variable turn does not have a method setTurn defined, as the error message states correctly. Probably you want something like this:
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
}
playerTurnObj.prototype = {
setTurn: function(turnToSet) {
this.playerTurn=turnToSet;
},
getTurn: function() {
return this.playerTurn;
}
};
Now your variable turn has two methods setTurn and getTurn that operate on the instance you created with new.
The setTurn and getTurn functions are private so they return undefined rather than invoking the function. You can do:
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
this.setTurn = setTurn;
this.getTurn = getTurn;
function setTurn(turnToSet) {
this.playerTurn=turnToSet;
}
function getTurn() {
return this.playerTurn;
}
}
You then have public setTurn and getTurn methods and can invoke them as follows:
var turn = new playerTurnObj();
turn.setTurn(1);
http://jsfiddle.net/Ht688/
What I make out of it is you need to return the object this in function playerTurnObj(). So your new code will look something like:
function playerTurnObj(set_turn) {
this.playerTurn=set_turn;
function setTurn(turnToSet) {
this.playerTurn=turnToSet;
}
function getTurn() {
return this.playerTurn;
}
return this;
}