I want to be able to tell if a function is noop. I was looking for a built in method such as angular.isNoop() but couldn't find anything. Is there anything that differentiates a noop?
A noop is simply a function that contains no operations. You can test for a specific noop function by using ===
For example;
console.log(x === angular.noop);
Will print true if x was assign the noop from Angular, but this will not work if x is using the noop from jQuery.
To check if a variable looks like a noop. You just need to see if the function string ends with {}. You can try something like this.
console.log(angular.isFunction(x) && /\{\}$/.test(x.toString()));
The above should work even in the code is minified.
A noop function has a name just like any other function. That name is noop. So you can check for it just by calling:
var theFunction = angular.noop;
theFunction.name === 'noop'
It is not a typical task, it is unlikely that the framework will have one.
function isNoop(fn) {
var trimRegex = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
try {
return !fn.toString().match(/{([\s\S]*)}$/)[1].replace(trimRegex, '');
} catch (e) { };
}
It does not check for noop statements within function, of course. The credits for trimRegex go to jQuery.
Related
Sorry for the noobish question, but nothing works for me today.
I'm creating a Phonegap application and have intergrated PushWoosh API into my app. And on receive push notification I want to run my previous functions again, so the data will be updated.
Pushwoosh has JS function like this:
document.addEventListener('push-notification',
function(event) {
var title = event.notification.title;
var userData = event.notification.userdata;
var notification = event.notification;
if (typeof(userData) != "undefined") {
console.warn('user data: ' + JSON.stringify(userData));
}
var object = JSON.parse(notification.u);
window.runPushFunctions(object.active, object.open); //Runs a jQuery function I have created..
}
);
Now window.runPushFunctions looks like this:
$(document).ready(function() {
window.runPushFunctions = function(active, open) {
if (active != null || active != undefined) {
$('.hubs-page').removeClass('hubs-active').hide().eq(active).show().addClass('hubs-active');
}
if (open == 2) {
$('html').addClass('hubs-opening');
}
//Trying to run functions from jQuery file that will get data from database and so on..
received();
sent();
checkFriends();
};
});
But I can't for some reason not run received(), sent(), checkFriends().
These functions is set like this in their own files like this:
(function($) {
'use strict';
function checkFriends () {
$.getJSON('url',function(data){
$.each(data,function(index,value){
//Do something with value
});
});
}
Im including files in this order:
file.js -> received(); sent();
file.js -> checkFriends();
file.js -> pushnotifications
Any help will be gladly appreciated
As the other answer here says, you are scoping your method definitions so they are not accessible anywhere outside the containing method.
(function($) {
This is a method definition. Any variables or functions non-globally declared within it cannot be accessed outside it. Therefore, you need to define the functions somewhere else or make them global for them to be accessible.
If you go for defining them somewhere else, you can simply move the function definitions to the top of the same file, outside of the (function($) {})() scope.
If you go for global definitions instead, you need to change the methods' defining lines slightly: instead of
function foo() { }
you need
window.foo = function() { }
This assigns an anonymously declared function to an object in the window scope, which is globally accessible. You can then call it using
window.foo();
or simply
foo();
since it is in the window scope.
I'm not exactly sure I'm understanding your question, but it looks to me like you are defining the function checkFriends inside of a function scope. If you need access to that function definition, you would need to declare it on an object that can be referenced from the global scope. Obviously the easiest way to do that would be to attach it to the window, though there are plenty of reasons not to do that.
window.checkFriends = function(){//code that does stuff};
I'm trying to call a js function within another one, but use the argument to specify the function. ie depending on the argument passed, it will call a different function
function toggle(n){
if (sessionStorage['toggle'+n]== 0){
check+n();
}
else
}
So, for example, if the argument 'Balloons' was passed as n, then it will call the function checkBalloons(). "check+n();" is not currently working here. Sorry for my lack of simple js syntax!
If the function is defined in the global scope (browser) you can do:
window["check"+n]();
or some tenants like Node.js you would access it from global object.
global["check"+n]();
if it is a part of some other object then you would do the same.
obj["check"+n]();
Functions and properties defined on an object can be accessed using [] convention as well. i.e obj["propFuncName"] will give you reference to it, so in case of methods you add () to invoke it.
If the function is global, you would do this:
window["check" + n]();
or, you could put your function in an object like so:
myNamespace = {};
myNamespace.checkSomething = function(){ /* ... */ }
// call it like this:
myNamespace["check" + n]();
The answers thus far are correct, but lack explanation.
In JavaScript, you cannot call a function by name when that name is a string. What you can do is retrieve a value from an object by name, and if that value happens to be a function, you can then call it. For example:
var myObject = {};
myObject.myFunction = function() { alert('test!'); };
// Get the property on `myObject` called `myFunction`
var theFunctionLookup = myObject['myFunction'];
// Since that property was a function, you can call it!
theFunctionLookup();
In the browser, functions that are defined in the global scope are attached to the window object. For example, this works:
function myFunction() { alert('test'); }
var theFunctionLookup = window['myFunction'];
theFunctionLookup();
You can shorten the last two lines into one:
function myFunction() { alert('test'); }
// Look up and call the function in one line.
window['myFunction']();
For the same reasons, you can use a dynamically-calculated string to look up functions.
function checkBalloon() {
alert('checking balloon');
}
function toggle(n){
if (sessionStorage['toggle'+n]== 0){
window['check' + n]();
check+n();
}
}
toggle('Balloon');
if you do this way:
if (sessionStorage['toggle'+n]== 0){
window["check" + n]();
}
will work
Let's start from the code:
function say(name) {
var ghost=function () {
function ghost() {
alert('!');
};
return body;
};
eval("var body=''+"+name+';');
eval(name+('=('+ghost).replace('body', body)+')();');
eval(name+'();');
}
function Baal() {
if ('undefined'===typeof ghost) {
say('Baal');
return;
}
ghost();
}
say('Baal'); // or just Baal();
Looks like that saying the devil's name invoke his presence (well, maybe he needs somebody for spiritual possession) ..
As you can see the ghost doesn't exist along with Baal, but we can invoke it since there're evals in say(name).
say(name) reassigns Baal to its code body as a closure and makes it captured a ghost method, that's how things work. But I'm trying to avoid eval ..
So .. let me reword the question:
How do I make a nonexistent(and not a member or global) method invocable without using eval?
Let me rephrase your question, just to make sure I’ve got it. Given a function, you want to put a new variable in its scope, without that scope being the global scope or a scope shared between the caller and the subject, without using eval (or the equivalent new Function and other hacks depending on the environment).
You can’t.
In the case you just mentioned, you could define one function, base(), that uses arguments.callee.caller.
Don’t do that.
The short answer: You don't.
That scope is not available. If you were to attach the scope then it would be available inside of the scope used. You could then access the method handles. I assume this is not what you were looking for, but here is what that would look like. demo
function say(name){
var methods = {};
methods.Baal = function(){
alert("!");
};
return methods[name];//this could invoke as well: methods[name]()
}
var handle = say('Baal');
handle();
What your evals break down to is something along these lines (although with dynamic content from string building - this is the end result)
function say(name) {
var Baal = (function () {
function ghost() {
alert('!');
};
return function(){
if ('undefined'===typeof ghost) {
say('Baal');
return;
}
ghost();
}
})();
Baal();
}
say('Baal'); // or just Baal();
Note that the meat of what happens here is from the function Baal, namely that it calls a hardcoded ghost() which in turn calls a hardcoded alert. Why go through all of this trouble to access a hardcoded function?
A better way would be to inject this function as a callback which expects some parameters to be injected.
jsFiddle Demo
function say(callback){
var params = "!";
if( typeof callback == "function" ){
callback(params);
}
}
say(function(params){
alert(params);
});
It's very difficult for me to read through your code and figure out what you are trying to accomplish with it, but it appears that you are trying to introduce a variable into the current scope so that you can call it. You cannot do this in javascript with the method that you demonstrated. Scoping only ever "flows down". By that I mean that a variable or function defined within a function will only be available to that function and any other functions defined therein. Your function named ghost will only ever be available within the function where it is defined, regardless of when that function is evaluated.
What you can do, however, is write a function that returns a function. You can then call that function and assign the result to a variable in the scope where you want to expose functionality. Doing that would look something like this.
function defineSpecialAlert() {
return function(name) {
alert(name + "!");
};
}
var newlyDefinedMethod = defineSpecialAlert();
newlyDefinedMethod("Baal");
So if I understand, it seems like you want to create an alias of eval: Something like
#Note this code is not intended as a solution, but demonstrates
#an attempt that is guaranteed to fail.
#
function myAlias(ctx) {
eval.call(ctx, 'var ghost = 42');
}
myAlias(this);
alert(ghost);
Javascript allows many funky sleight-of-hand tricks especially with closures, but this is maybe the one impossible thing that javascript cannot do. I've tried at length to do this exact same thing, and I can tell you that you'll run into nothing but complaints from the browser, saying that eval cannot be re-contexted or aliased in any way.
I have many js methods that uses global variables like:
function DoSomething() {
var val=$('#'+clientId).val();
.
.
.
}
DoSomething uses clientId variable. The problem is that clientId is not always declared and therefore I get an exception of undeclared variable.
I have many places like this and add if (typeof clientId == "undefined") check everywhere is a lot of work and code duplication (duplication of the check). Is there I can workaround it? for example use a method that returns null if the variable is not declared? (In such way I can control on the return value in case of an undefined for example)
It seems to me that your code is just busted if you have code paths that attempt to use a global variable before it is defined. Either you need to give it a default value, you need to reorder the loading or execution of your code or you need to prevent code from running when your environment hasn't been initialized.
It is possible to initialize a variable if and only if it hasn't already been defined like this:
var clientId = clientId || "foo";
You could put this at the top of any module that uses it. This would initialize it with whatever value you want if and only if it wasn't already initialized.
You could also build yourself an accessor function that you would use instead of directly accessing the variable like this:
// put this somewhere early in the JS loading process
function getClientId() {
if (typeof window.clientId !== "undefined") {
return(window.clientId);
} else {
return("foo"); // whatever default value you want to return here
}
}
// use it like this:
function DoSomething() {
var val=$('#'+getClientId()).val();
.
.
.
}
Or, you can make a global function that will test it:
function isClientId() {
return(typeof window.clientId !== "undefined");
}
// use it like this:
function DoSomething() {
if (isClientId()) {
var val=$('#'+clientId).val();
.
.
.
}
}
Just an idea: all variables are properties of a namespace, up to the global namespace (in a browser, that's window). A property that's not assigned evaluates to undefined. So if you want to know if a variable is assigned, you can use if (property in namespace). If it concerns a global variable in a browser: if (clientId in window). Now you can make a function out of that:
function exists(label, namespace){
namespace = namespace || window;
return namespace[label] || false;
}
// possible usage
function DoSomething() {
var val=$('#'+( exists('clientId')||0) ).val();
// ...
}
Global variables are evil and are to be avoided if at all possible.
In the example you give, it would be much better to declare client ID as a parameter, like so:
function DoSomething(clientId) {
var val=$('#' + clientId).val();
.
.
.
}
This way, you are not affected by issues with global variables and there are no side effects (value changes caused by other methods) to worry about.
Good luck!
try :
var isExists =clientId || false;
but be careful
if ClientId==0 it will show you false.
I use:
if (typeof (foo) != 'undefined')
alert ('foo is defined');
If the variable itself is declared (as opposed to just having an undefined value), then you can simply use ( clientId || 'default value' ). This requires that you have var clientId; or something similar in the global scope (which is bad practice, BTW).
If you do not have a guarantee that clientId has been declared somewhere, then using the above construct will still throw an undefined variable error. In that case, you can use this: ( typeof clientId == 'undefined' ? 'default value' : clientId ).
While i like the answers, I go the simple way... Just declare var clientId; on top of your script. If you don't pass it any values then :
var clientId;
if(!clientId){
//will reach here cause declared but with no value
}
but
var clientId;
clientId = 132;
if(!clientId){
}else{
//will reach here cause it has a value
}
so
function DoSomething() {
if(clientId){
Would work
I defined a global Javascript function:
function resizeDashBoardGridTable(gridID){
var table = document.getElementById('treegrid_'+gridID);
.....
}
After this function was used a few times, I want to remove(or undefined) this function because the Procedure code should be called again. if somebody try to call this method we need do nothing.
I don't way change this function right now.
so re-defined this function may be one way:
function resizeDashBoardGridTable(gridID){
empty,do nothing
}
Thanks. any better way?
Because you're declaring it globally, it's attached to the window object, so you just need to redefine the window function with that name.
window.resizeDashBoardGridTable = function() {
return false;
}
Alternately you could redefine it to any other value or even to null if you wanted, but at least by keeping it a function, it can still be "called" with no detriment.
Here's a live example of redefining the function. (thanks TJ)
An additional reason for pointing out that I'm redefining it on the window object is, for instance, if you have another object that has that function as one if its members, you could define it on the member in the same way:
var myObject = {};
myObject.myFunction = function(passed){ doSomething(passed); }
///
/// many lines of code later after using myObject.myFunction(values)
///
/// or defined in some other function _on_ myObject
///
myObject.myFunction = function(passed){}
It works the same either way, whether it's on the window object or some other object.
how about using a var?
// define it
var myFunction = function(a,b,c){
console.log('Version one: ' + [a,b,c].join(','));
}
myFunction('foo','bar','foobar'); // output: Version one: foo,bar,foobar
// remove it
myFunction = null;
try { myFunction(); console.log('myFunction exists'); }
catch (e) { console.log('myFunction does not exist'); }
// re-define it
myFunction = function(d,e,f){
console.log('Version two: ' + [d,e,f].join(','));
}
myFunction('foo','bar','foobar'); // output: Version two: foo,bar,foobar
OUTPUT:
[10:43:24.437] Version one: foo,bar,foobar
[10:43:24.439] myFunction does not exist
[10:43:24.440] Version two: foo,bar,foobar
The simplest approach is to set the function (treat it as a variable) to null. This works even if you don't declare it as a var. Verified this on IE.
resizeDashBoardGridTable = null
If the functions needs to be called 1 time you use an anonymous self invoking function like this:
(function test(){
console.log('yay i'm anonymous');
})();
If you have to call the function multiple times you store it into a var and set it to null when you're done.
Note: You don't have to name an anonymous function like I named it test. You can also use it like this:
(function(){
console.log('test');
})();
The reason I do name my anonymous functions is for extra readability.