I know. It is possible to dynamically load JavaScript and style sheet file into header of document. In the other hand, it is possible to remove script and style sheet tag from header of document. However, loaded JavaScript is still live in memory.
Is it possible to destroy loaded JavaScript from web browser memory? I think. It should be something like the following pseudo code.
// Scan all variables in loaded JavaScript file.
var loadedVariable = getLoadedVariable(JavaScriptFile);
for(var variable in loadedVariable)
{
variable = null;
}
// Do same thing with function.
Is it possible to create some JavaScript for doing like this?
Thanks,
PS. Now, you can use xLazyLoader and jQuery for dynamic loading content.
If the loaded script is assigned to a window property, for instance with the module pattern like so:
window.NiftyThing = (function() {
function doSomething() { ... }
return {
doSomething: doSomething
};
})();
or
window.NiftyThing = {
doSomething: function() { ... }
};
or
NiftyThing = {
doSomething: function() { ... }
};
Then you can delete the property that references it:
delete window.NiftyThing;
...which removes at least that one main reference to it; if there are other references to it, it may not get cleaned up.
If the var keyword has been used:
var NiftyThing = {
doSomething: function() { ... }
};
...then it's not a property and you can't use delete, so setting to undefined or null will break the reference:
NiftyThing = undefined;
You can hedge your bets:
NiftyThing = undefined;
try { delete NiftyThing; } catch (e) { }
In all cases, it's up to the JavaScript implementation to determine that there are no outstanding external references to the loaded script and clean up, but at least you're giving it the opportunity.
If, as Guffa says, the loaded script doesn't use the module pattern, then you need to apply these rules to all of its symbols. Which is yet another reason why the module pattern is a Good Thing(tm). ;-)
It might be possible to remove a Javascript file that has been loaded, but that doesn't undo what the code has done, i.e. the functions that was in the code are still defined.
You can remove a function definition by simply replacing it with something else:
myFunction = null;
This doesn't remove the identifier, but it's not a function any more.
Related
Im building a webapp where i load the main page with its own javascript file in the index.html then the nav is calling all other pages in a div without a browser refresh using $.ajax and attaching specific script for each page in the div too with $.getScript.
Sometimes i needs to access a method declared in the main page javascript from within the div loaded javascript so what i generally do is attach the main method to document, exemple, instead of just:
let doThis = function(num){
// do your stuff
}
i do this
document.doThis = function(num){
// do your stuff
}
This way i can easily access it from any other javascript file loaded at different levels.
Thing is i feel its not a good practice, what would then be the good practice? or is it acceptable one?
If you are not using any bundler,then 'Revealing Module Pattern' can be used as a good practice here. This will allow the syntax to be more consistent and in this case, will make it easier to tell which of the functions can be accessed globally.
window.mainPageModule = (function () {
var privateVar = "abcd",
function privateFunction() {
//Do some private stuff here
}
function publicSetValue(value) {
privateVar = value;
}
function publicGetValue() {
return privateVar;
}
// Reveal desired functions to public
return {
doThis: publicSetValue,
getThis: publicGetValue
};
})();
Then, to access the public function anywhere globally
mainPageModule.doThis("1234")
Is it possible to pass a javascript-variable to a script on another site?
I would like to do something like this:
This code is in a page on www.myfirstsite.net:
<script>
var ID = 'randomstring';
</script>
<script src="http://www.mysecondesite.net/processingscript.js"></script>
How can I read the var ID in the script on mysecondsite.net?
Update:
My question is wrong, as explained in the helpful answers from #vihan1086 and others.
Why to never do that
You should never declare variables like that, it has been described here
Then What?
On one page, do:
window.globals = {};
window.globals.my_variable = 'ABC';
On the script, add:
var globals = window.globals;
globals.my_variable;//Gets 'ABC'
This will keep all variables safe in a global place. Then we can get all global variables at once, increasing speed.
Don't forget to wrap all your code in something like:
(function() {
//Code here
})();
Functions
To make this easier I made functions:
setSharedVar (name, value) {
if (!"globals" in window) {
window.globals = {};
}
window.globals[name] = value;
}
getSharedVar (name) {
if (!"globals" in window) {
window.globals = {};
return null;
} else if (!name in window.globals) {
return null;
} else {
return window.globals[name];
}
}
Examples
Script 1:
setSharedVar('id', 5);
Script 2:
if (getSharedVar('id') === 5) {
alert('Success!');
}
Alerts 'Success!'
In your other script, ID will already exist and you can just use it.
Javascript runs in an environment attached to you web page, so as long a you dont change pages you can setup variable and includes other scripts that will have access to them.
So what you are proposing should work
However you should know that running script from other websites can be seen as dangerous and is therefore forbiden by some navigators/plugins ... so you should try and avoid it if possible (by providing a copy of the script on your website)
Hi,
I have my main file in which I include my javascript file.
In my javascript file I have this
$(document).ready(function(){
//some functions here
});
I want all the functions just available to this page and I know you can kinda conceal them to outside world of javascript by doing something like
(function(){
$document.ready(function(){
//my functions
)};
}).init();
but I am not 100% sure how would it be called or whether its even the right way.
Anyone shedding light on this would be a great help!
In javascript everything declared inside a function is only available inside that function (except for when you declare a variable without the keyword var).
So everything inside the function that you pass to $().ready() is only available inside that function.
$(document).ready(function () {
//all code here is scoped inside this function, so it can't be accessed
// outside of this function
});
Like the first comment says you can't hide them from the user, if they really want to see it, they will see it.
You can clean them up in a way if you really wanted to, something like
var mySpace = {};
mySpace.init = function() {
// your init functions here
};
in doc ready you just call
mySpace.init();
I am not sure if this is what you wanted but it is the way I understood the question
(function(){
var secret1 = function(msg) {console.log("Secret Message:" + msg);}
$document.ready(function(){
secret1("this can only be called from within");
)};
})();
secret1("this will cause a script error");
It sounds like the thing you are looking for is a 'javascript obfuscator'. Here is an example one. It makes the code much harder to read and copy. But as others have said, you can't actually fully hide javascript.
The problem here is that JavaScript is intrinsically a client-side scripting language unless using a server-side javascript application such as node.js.
As long as JavaScript is being used in this way, the entirety of your code will be downloaded much like downloading a .txt file from a website. The only real difference is that the ".js" extension and its inclusion in html <script> tags or in an AJAX call will force the user's browser to render it as JavaScript.
If you want to make the script a little harder for the user to find, however, this is doable. I recommend having your website retrieve the script via AJAX and appending it to the DOM. You can do this with require.js or by using Kickstrap and making your script into an "app." The script won't appear as a link in the DOM and the user would really have to search for it. You can make it even more difficult (without compromising the integrity of your site) by minifying the script. This will make it run faster while inadvertently making it less human-readable on the front end.
In JavaScript there is only function scope (the exception argument in try-catch being an exception). ES5 will let you use let (no pun intended) to achieve block scope but it wont be usefull untill majority of UAs implement it.
So your functions are concealed from the outside world, if with outside you mean outside the dom ready event.
$( document ).ready( function () {
var myFunc = function () {};
} );
myFunc();// <- ReferenceError: myFunc is not defined
You can't really hide the functions, as it's in the source code of a file downloaded by the client, but you can make it so they can't access your functions from javascript.
(function() {
var doStuff = function() {
// Not Accessible
console.log('You can\'t reach me!');
}
return {
'init': function() {
// Accessible
doStuff();
}
}
})().init();
If you are talking about Access Modifiers like public, private etc. Then check out this article on how Javascript handles this. Here are the key components:
//constructor function (class)
function Maths(x, y) {
//public properties
this.x =x;
this.y = y;
//public methods
this.add = function () { _sum = x + y; return _sum; }
this.mod = function () { _mod = x % y; return _mod; }
//public method calls private method
this.show = function () {
this.add();
this.mod();
showResult();
}
//private variables
var _sum=0;
var _mod=0;
//private methods
function showResult() {
alert( "sum: " + _sum + ", mod: " + _mod );
}
}
//end function
//create instance
var plus = new Maths(3, 4);
plus.show();
//static method multiply, you can use it without instance of Maths
Maths.multiply = function (x,y) { return x * y; }
//call static method by constructor function (class) without instance of Maths
var result = Maths.multiply(5,7);
alert(result);
//output: 35
I'm looking to encapsulate my javascript inside a namespace like this:
MySpace = {
SomeGlobal : 1,
A: function () { ... },
B: function () { ....; MySpace.A(); .... },
C: function () { MySpace.SomeGlobal = 2;.... }
}
Now imagine that instead of a few lines of code, I have about 12K lines of javascript with hundreds of functions and about 60 globals. I already know how to convert my code into a namespace but I'm wondering if there's a quicker way of doing it than going down 12K lines of code and adding MySpace. all over the place.
Please let me know if there's a faster way of doing this.
Thanks for your suggestions.
I like to wrap up the namespace like so. The flexibility is huge, and we can even separate different modules of the MySpace namespace in separate wrappers if we wanted too. You will still have to add some sort of _self. reference infront of everything, but at least this way you can change the entire name of the namespace very quickly if need be.
You can see how with this method you can even call _self.anotherFunc() from the 1st module, and you'll get to the second one.
(function (MySpace, $, undefined) {
var _self = MySpace; // create a self-reference
_self.test = function () {
alert('we got here!');
_self.anotherFunc(); // testing to see if we can get the 2nd module
};
_self = MySpace; // reassign everything just incase
}(window.MySpace = window.MySpace || {}, jQuery));
$(function () {
MySpace.test(); // call module 1
MySpace.callOtherModule(); // call module 2
});
// Here we will create a seperate Module to the MySpace namespace
(function (MySpace, $, undefined) {
var _self = MySpace; // create a self-reference
_self.callOtherModule = function () {
alert('we called the 2nd module!');
};
_self.anotherFunc = function () {
alert('We got to anotherFunc from the first module, even by using _self.anotherFunc()!');
};
_self = MySpace; // reassign everything just incase
}(window.MySpace = window.MySpace || {}, jQuery));
jsFiddle DEMO
Wrap a function body around your existing code to use as scope, hiding everything from global - this will allow you to do internal calls without pasting Namespace. prefix everywhere, neatly hide things you don't want everyone else to see, and will require minimal changes as well.
After that, decide what functions you want to "export" for everyone and assign them to properties of object you want to use as "namespace".
Just wanted to know if it was a good JavaScript practice.
Let's say I have many Web pages that all call an initialization function "init()", would it be the right thing to use an IIFE inside my pattern to run the function everytime the script is loaded?
var foo = (function() {
var bar = "something";
(function init() {
// Do something crazy that's gonna be the same across all my web pages
// like adding an event listener or something
// ...
document.write('page init...');
}());
function privatePage1() {
// This stuff is gonna be used only in page1.html via foo.privatePage1
document.write('page 1' + bar);
}
function privatePage2() {
// This stuff is gonna be used only in page2.html via foo.privatePage2
document.write('page 2' + bar);
}
return {
privatePage1: privatePage1,
privatePage2: privatePage2
}
}());
This is a pretty subjective area, but here's my take:
When you use the module pattern, you're providing a contained set of functionality to the rest of your code. It's essentially a mini-library.
In general, I wouldn't expect a library to do anything when I load it, other than initialization steps that are entirely internal to the library (e.g. setting up the configuration, instantiating a few necessary objects, etc) - nothing that actually affects the DOM or otherwise significantly alters the environment (which is why I've never been entirely comfortable with libraries like Date.js or Prototype that change the prototypes of basic objects).
There are a couple of reasons for this, but the main one is that I don't want to have to worry about the load order of my libraries/modules, other than simply managing dependencies. Independent modules shouldn't affect each other at all. When you manipulate the DOM in your module at load time, sooner or later you'll realize that another piece of your code is expecting the DOM to be in a certain state at a certain time, and that you now have to care about whether you load your module before or after that time. This is an extra bit of complexity that's essentially hidden in the script tag that loads your module.
The other issue here is portability and adaptability. Maybe you'll want to use your module in another project with another DOM setup. Maybe you'll want to pass a different DOM element or config variable to the init() function on a specific page. If you execute init() automagically, you lose the opportunity for configuration.
So what I generally do is to set the init() method as an attribute of the returned module object:
var foo = (function() {
function init() {
// Do something crazy that's gonna be the same across all my web pages
}
//...
return {
init: init,
// etc
}
}());
and then call it as needed elsewhere in my code:
foo.init();
Yes, this adds an extra line of redundant code to the initialization for all my pages (though this is probably just one other script anyway, so the added weight is all of 11 characters). But it allows me a more fine-grained control over when the module is initialized, and offers a hook for configuration arguments when I (inevitably) determine I need them later.
Is the init() function the same across web pages? If so, this is what I'd do:
var foo = (function()
{
init();
return {};
}());
If not, I don't see a reason to use an IIFE, and would simplify your original code like so:
var foo = (function()
{
/* body of the original IIFE here */
return {};
}());