This is most likely a very simple one.
I have created a game in canvas and js. However I stumbled upon a problem. As I can access the variables and code inside the chrome console, I can change f.ex. the player score to whatever I'd like. This is not very good.
Is there some way I can make the file and variables non accessible through the console for players to use?
Thanks!
You can put the whole script into an IIFE so that any variables declared will be scoped to the just-invoked function, rather than be on the top level and accessible anywhere. For example:
(function() {
var playerName = 'bob';
var turnCount = 1;
// do stuff with playerName and turnCount,
// they won't be accessible or changeable from the outside
// you can declare functions and such here as well
// which will also only be accessible from the inside
})();
Like this, referencing playerName from the console will fail.
you can use a proxy.
javascript proxy
or you can make an IIFE and expose only the required functions such as:
var App = (function() {
var test = '';
var init = function() {
App.test = 'test';
};
return {
init: init
};
})();
or define your properties as not writable with Object.defineProperty()
Related
this is my current code
function includeClass(classname, ctx) {
var txt = fs.readFileSync("socket.io/" + classname + ".js");
return txt;
}
//define globals here
var _PLAYERS = {};
var _SPAWNPOINTS = [];
vm.runInThisContext(includeClass("vector"));
vm.runInThisContext(includeClass("class"));
vm.runInThisContext(includeClass("connectionHandler"));
vm.runInThisContext(includeClass("game"));
But that way, class.js file can't access variables from global scope or other files. because now i get errors like, _PLAYERS or require is undefined. I've tried eval() too, but it didn't do anything at all.
How can I run these js scripts in main script so they get interpreted as 1 whole?
https://nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_options:
Running code does not have access to local scope, but does have access to the current global object.
Your _PLAYERS variable is not truly global, it is local to your script. As well as some other variables (like require) which are also in the module scope.
You can try to assign the needed variables to global object, however, I am not well aware what side effects and complications may follow.
Hello I am new JavaScript unit testing and I'm using Mocha.js and Chai.js
What I want to do is simply figure out how to check the value of a global variable in a seperate js file. Here is my code
Here is the main.js file (code to be tested) Just has the variable I want to test against.
//main.js
var foo = 9;
Here is my test file
var assert = require("assert")
var expect = require('chai').expect
var fs = require("fs")
var vm = require("vm")
function include(path){
var code = fs.readFileSync(path,'utf-8');
vm.runInThisContext(code,path);
}
describe('Global', function(){
include('lib/main.js');
it('Should check if value is matching', function(){
expect(foo).to.equal(9);
});
});
Again, I'm new to unit testing in JavaScript. Any help will be greatly appreciated. The error I get back is foo is not defined which tells me that it can't access the variable, so how can I access it? Thank you in advance for the help.
var foo = 9; does not declare a global variable, it declares a local variable. In Node.js, a local variable declared in the outermost scope of a module will be local to that module.
If you want to test the value of a local variable declared in another file, your best bet is probably to read the contents of that file into a string (using fs.readFileSync, perhaps) and then eval() the string, which should define the variable in the current scope.
That will only work if the local variable is declared in the file's outermost scope. If it's a local variable inside a function, for example, you're out of luck (unless you want to do some gnarly string parsing, which would stretch the bounds of sanity).
Your global object is usually window
a global var foo = "test"; is the same as window.foo = "test"; or window['foo'] = "test";
Window is not defined when mocha is run in node, but this blog post uses "this" combined with a self-invoking function to get the same result.
listofLOBs: function(data) { //passing data
var returnLOB = [];
console.log(data);
for (var i1r= 0; i1r < data.length; i1r++) {
var lob = new LOBslist();
lob.name = data[i1r].name;
lob.id = data[i1r].id;
returnLOB.push(lob); // storing in returnLOB
}
console.log(returnLOB[1].name);
$('#mainWrapper').find('select[name="lob-select"] option:selected').text(returnLOB[1].id); //using the returnLOB's object data to populate dropdown
return returnLOB;
}
In the above function i am storing objects in the returnLOB array and using it inside the function itself to populate a dropdown.
But say this is file1.js, i would like to access returnLOB's values from file2.js How can i do that? Thanks in advance.
Note: i have declared returnLOB[] globally too.(outside the above function)
To do what you want, you just need to remove var from your function so that you're not creating a local variable that shadows the global variable you've created in another file.
listofLOBs: function(data) {
// Here you're setting a global instead of a local
returnLOB = [];
You probably know this is a bad idea, and it would be better if you restructure your code so that you don't need a global
A simple solution is to have all code that needs the variable in one place with a self-executing function so your global is only exposed to the code that needs it
(function(){
var returnLob;
... contents of file 1, which write to returnLob
... contents of file 1, which read returnLob
})()
As long as you include file1.js before file2.js, it will work. Take jQuery as an example - or any JS library for that matter - if you include its source file before your code, you can use functions within it.
You want to include the files in the above order, then you can just call the function (listofLOBs()) in file 2.
Additionally, your variable declaration within the function is incorrect.
var returnLOB = []; // You're declaring a global.
should be
returnLOB = []; // because the variable is already declared - you just want a local copy.
Hope this helps.
You should be able to access any globals between files. In your example you defined returnLOB inside of a function so that won't be accessible but the one you claimed to have defined globally will be accessible by both files.
This also has been asked before so check out:
Javascript: Scope of a Variable across different Javascript files
My application is accessing a third party external JavaScript file that I cannot alter.
Within the file is an object defined similarly to as follows:
object_1 = (function(){
var object_1_var = 'object_1_var_value';
return {
obj_1_func: function() {
console.log(object_1_var);
}
}
})(window);
I need to be able access the object_1_var within the object, but I'm struggling to access it.
object_1.v // returns undefined
object_1.obj_1_func() // returns the value via console, but I need to assign it to a var.
I have tried extending the object using as follows: (Using jQuerys $.extend())
object_2 = (function(){
return {
obj_2_func: function() {
return object_1_var;
}
}
})(window);
$.extend(object_1, object_2);
var my_var = object_1.obj_2_func(); // returns 'Uncaught ReferenceError: object_1_var is not defined'
What can I do to be able to access object_1_var?
You will not be able to access the variable. It happens to be a private member. Private members of an object can be accessed only by its member functions.
Read this.
object_1_var is a lexically scoped local variable.
That means that it can't be accessed by extending object_1 outside of its original definition.
The only way it can be accessed is by adding functions within the original lexical scope in which it was declared:
object_1 = (function(){
var object_1_var = 'object_1_var_value';
return {
obj_1_func: function() {
console.log(object_1_var);
}
var_1: function(x) {
if (typeof x !== 'undefined') {
object_1_var = x;
} else {
return object_1_var;
}
}
}
})(window);
but since you can't modify object_1, you're out of luck, I'm afraid!
Make it public, like this:
object_1 = (function(){
var object_1_var = 'object_1_var_value';
return {
obj_1_func: function() {
console.log(object_1_var);
},
object_1_var: object_1_var
}
})(window);
EDIT
If unable to edit the javascript (such as in a third party library - sorry for omission) then you will not be able to have access to object_1_var as it's scope is local to the closure object_1.
What you are trying to accomplish is impossible in JS.
With the construction of object_1 the variable goes out of scope of that method. The reason why the logging function can access the variable is what we call 'a closure'.
Sadly, object_1_var isn't accessible in this example. The variable is defined as local to within that particular function - the only reason that the other functions can see it is because they are also defined within that function. This "closure scoping" is an interesting feature in JavaScript that you don't see very often elsewhere, but is the only real way of defining "private" variables in JavaScript Objects.
Hope that helps!
In a worst case scenario, in the past I've worked around this sort of issue by effectively overwriting the definition of an object that was previously defined elsewhere - mainly in Greasemonkey scripts - but I wouldn't condone this for production uses!
The trick here is to just copy the entire piece of script into your own. It's ugly as hell, but it might just work! (YMMV)
I'm working on a large project that is organized like so:
Multiple javascript files are included as needed and most code is wrapped in anonymous functions...
// wutang.js
//Included Files Go Here
// Public stuff
var MethodMan;
// Private stuff
(function() {
var someVar1;
MethodMan = function(){...};
var APrivateMethod = function(){...};
$(function(){
//jquery page load stuff here
$('#meh').click(APrivateMethod);
});
})();
I'm wondering about a few things here. Assuming that there are a number of these files included on a page, what has access to what and what is the best way to pass data between the files?
For example, I assume that MethodMan() can be accessed by anything on any included page. It is public, yes?
var someVar1 is only accessible to the methods inside that particular anonymous function and nowhere else, yes? Also true of var APrivateMethod(), yes?
What if I want APrivateMethod() to make something available to some other method in a different anonymous wrapped method in a different included page. What's the best way to pass data between these private, anonymous functions on different included pages? Do I simply have to make whatever I want to use between them public? How about if I want to minimize global variables?
What about the following:
var PootyTang = function(){
someVar1 = $('#someid').text();
//some stuff
};
and in another included file used by that same page I have:
var TangyPoot = function(){
someVar1 = $('#someid').text();
//some completely different stuff
};
What's the best way to share the value of someVar1 across these anonymous (they are wrapped as the first example) functions?
You're right - any variable declared inside the anonymous function stays inside the anonymous function. So from the first example, MethodMan will be available to everything, and someVar1 is indeed private.
When you talk about 'including' files, imagine you just copy and paste the code from all the separate files into one big file. This is essentially what happens. If you want someVar1 to be available to different "modules" (since that's what you're emulating w/ the anonymous functions), then declare it outside any of the modules, e.g.:
var someVar1 = "initialValue";
(function() { //module 1
var PootyTang = function(){
someVar1 = $('#someid').text();
//some stuff
};
})();
(function() { //module 1
var TangyPoot = function(){
someVar1 = $('#someid').text();
//some stuff
};
})();
In this case, since someVar1 is global, they will access the same variable. But note that if you did this instead:
(function() { //module 1
var TangyPoot = function(){
var someVar1 = $('#someid').text();
//some stuff
};
})();
You'd be creating a separate local variable called someVar1 that wouldn't affect the global.
You could use jQuery's event mechanism (bind and trigger) to pass data in a loosely coupled way:
(function() { //module 1
var Observable = function() {
// [..]
var $element = $('#someid');
$('body').trigger('Observable:init', {element: $element});
};
})();
(function() { //module 2
var Observer = {
onInit: function (e) {
}
};
$('body').bind('Observable:init', Observer.onInit);
})();