Way to access anonymous objects' methods - javascript

There is a website, which uses this code below to create website functionality:
$(document).ready(function(){
{
function I_WANT_TO_ACCESS_THIS_METHOD(){
CODE HERE
},
SOME OTHER CODE
}
});
I want to update this website with a greasemokey script, but I don't want to duplicate code already written. That's why I want to access methods that are part of such objects (in the code above it is the I_WANT_TO_ACCESS_THIS_METHOD()).
I'm not a JS master and I'm not sure if it is even possible, but I think that this is the right place to ask ;)

I_WANT_TO_ACCESS_THIS_METHOD() is not a method of an object, but just a function defined inside another function. So you can't access it outside that function(the domcument ready callback function) scope.

Related

Django 3 by example bookmarklet_launcher.js

Following is a piece of code in the Django 3 by example book we can use to bookmark in a browser and upon clicking the bookmark, the code in it will be executed.
Can anyone please help me understand this code?
(function(){ if (window.myBookmarklet !== undefined){ myBookmarklet(); } else { document.body.appendChild(document.createElement('script')).src='https://127.0.0.1:8000/static/js/bookmarklet.js?r='+Math.floor(Math.random()*99999999999999999999); } })();
Why do we need to put the function inside parenthesis? (function.....)()
How the browser executes the code. We put a javascript tag at the start of the code.
JavaScript:(function.....)()
what is this function myBookmarklet() and when if statement will be actually executed? How will the window object have myBookmarklet property?
Any relevant resources will be appreciated. Thanks a lot
It's because it's an anonymous function, it has no name. Because it has no name and needs to be executed, it has to be surrounded with parenthesis to be able to run it by calling it with () at the end.
Exactly like that. If you want to write a function that will not be needed in any other place, you can define it without a name so it's anonymous. To call it, see 1.
Before that js code, the HTML file has probably a series of <script> tags where it defines certain dependencies, in this case javascript files. One of those js files has assigned myBookmarklet to window, like this: window.myBookmarklet = //... a function definition. The code you posted is checking if window.myBookmarklet !== undefined before calling that function.

Overriding core JS commands?

I'm trying to modify/limit/prevent access to certain JS commands of my browser. For example commands like navigator.clipboard; However, I'm not sure how to approach this.
Is it possible to override these commands with user-defined javascript injected in the page, or do i have to edit the browser's javascript compiler and re-compile it from source for this?
I'm not really familiar with browsers and want to save time by knowing a general direction to follow. Thanks
First of all navigator.clipboard is not a function, but here is an example using the read function of navigator.clipboard:
navigator.clipboard.read = function (originalFunction) {
return function (yourParamsYouWantForThisFunction) {
// Do Stuff you wanna do before the real call. For example:
console.log(yourParamsYouWantForThisFunction);
// Call the original function
return originalFunction.call();
};
}(navigator.clipboard.read); // Pass the original function reference as a parameter
You may wonder, why there are two function statements:
The first one is there, so that we can pass the original function at runtime. If we would not do that, we would not be able to access the original navigator.clipboard.read function.
The second function is the actual function, that you will be using later, when you call navigator.clipboard.read().

Overriding jQuery function loses 'this' scope

I am trying to implement the following answer from another question:
https://stackoverflow.com/a/26469105/2402594
Basically I need to add an extra check to a jQuery function. The following code is in jQuery library:
But I can't modify the original jQuery, so I am creating a patch in a separate file. What I am doing is overriding the find function and add functionality as follows:
(function() {
var originalFind = jQuery.fn.find;
jQuery.fn.find = function () {
try {
document === document;
}
catch (err) {
document = window.document;
}
return originalFind.apply(this, arguments);
};
})();
The function is overridden correctly, however, when the code calls 'find', my 'try' doesn't throw any exception when it should because the scope is different than the one inside the Sizzle function, so the original issue is still there.
I have also tried duplicating all of the Sizzle code, adding my modification and assigning it to jQuery.fn.find as done above, however the scope issue is still there and some crashes happen.
I need 'document' to be set before it reaches the following check or it crashes due to permission denied:
How could I share the scope so that the try/catch can be done correctly? Is it even possible? Any other ideas?
Thank you
As we all known, JavaScript has function scope: Each function creates a new scope. Scope determines the accessibility (visibility) of these variables. Variables defined inside a function are not accessible (visible) from outside the function.
So, if the document is defined in the JQuery library function, I think you can't access it. You could try to define a global variable to store the document, then, you can access it in the JQuery library function and the override function.
More details about Javascript Scope, check these links: link1 and link2

How should I store my javascript variables?

I am currently coding in this way:
<script type="text/javascript">
var linkObj;
Is this a safe way to store data? My concern is what if a jQuery or other plug-in was to also use the variable linkObj. Also if I declare my variable like this then can it also be seen by other functions in scripts located in other js files that I include?
$(document).ready(function(){
var linkObj;
});
as long as you use the var keyword, any variable defined in that scope won't be accessible by other plugins.
I you declare a variable this way it will be accessible to all scripts running on the page.
If you just want to use it locally, wrap it in a function:
(function() {var linkObj; ... })()
However, this way nothing outside of the function will be able to access it.
If you want to explicitly share certain variables between different scripts, you could also use an object as a namespace:
var myProject = {}
myProject.linkObj = ...
This will minimize how many global names you have to rely on.
Wrap it in a closure:
<script type="text/javascript">
(function() {
var linkObj;
// Rest of your code
})();
</script>
This way no script outside your own will have access to linkObj.
Is this a safe way to store data?
This is not storing data per se, it's only declaring a variable in a script block in what I assume is an HTML page. When you reload the page in the future, it will not hold previous values.
My concern is what if a jQuery or other plug-in was to also use the variable linkObj.
That's a valid concern, like others have pointed out. However, you would expect plugins not to rely on scope outside the plug-in. This shouldn't impact a lot as good plug-in design would likely prevent this from happening.
Also if I declare my variable like this then can it also be seen by other functions in scripts located in other js files that I include?
Yes. As long as their execution is triggered after your script block gets loaded. This normally follows the order in which your script declaration appears in the page. Or regardless of the order they appear on the page if they are executed, for example, after the jQuery DOM 'ready' event.
It's common to hear that is good to avoid 'global namespace pollution', which relates to this concern. To accomplish that you can use a function to contain code, and directly invoke that function in your script block.
(function () {
var a = 1; // the scope is within the function
alert('The variable a is equal to: ' + a);
}) (); // the parenthesis invoke the function immediately

send data to JS file without using global variables

I need to send data in a HTML page to a script file that is loaded in that page. The simplest way i can think of is to use a global variable which is defined in the page and accessed in the script file.
We all know global state is bad, so i started thinking about the options available for passing data from HTML page to script file without using global state. I cant find (or think of) any.
I am curious whether this is possible. Any ideas?
It really depends what you're doing. In general, I wouldn't advise this methodology, but it's something to consider depending on your circumstances. For the sake of this example, I'll assume you're using jQuery (if not, replace the document.ready with whatever you want to use for onDOMReadyStateChange monitoring).
In the HTML:
<script type='text/json-data' id='some_data_set'>
{ 'foo': 'bar', 'baz': 1 }
</script>
In the JavaScript:
$(function() {
var myData = JSON.parse($('script#some_data_set').html());
// YOUR CODE GOES HERE
});
Nope. All the javascript scope starts from a global level, therefore you must have at least one global reference to your data.
Let's say you wanted to store a list of products and events:
var myGlobalData = { "products":<products>, "events":<events> };
Where <products> and <events> are two different data blocks.
If you're paranoid on global objects, you can simply delete the reference point (thus it's contents) after you finished using it, as follows:
delete window.myGlobalData;
One option is to scope your data. For example, in JS file you can define an object like:
var processor = {
function setData(o) { // do stuff
}
};
Then in your HTML you know that the data is scoped to the processor. So you can do something like:
processor.setData({someData});

Categories