I am getting this error in chrome while mozilla is handling good. I am getting this error to a function which is like this
function abc( xyz = false){ "My logic" }
Error is pointing to '=' operator. please help with this.
That is a standard of ECMASCRIPT version 6 and it's called Default parameters. So it might be not available in your chrome version while FF has.
You can achieve the same by two ways:
function abc( xyz ){ "My logic" }
var pVal = mightbe || false;
abc(pVal); //<---- now pass it here;
or:
function abc( xyz ){
// before processing anything you can do this
var o = xyz || false; // if there is any value in the xyz then that will
// be assigned otherwise false will be the default value.
"My logic"
}
This is ES6 syntax, most browsers only support very few ES6 features, you can check from here: https://kangax.github.io/compat-table/es6/ (In your example you used default function parameters)
If you want to write ES6 syntax (which is quite appealing in many ways), you can use some code transpiling tool like babel: https://babeljs.io/
Related
Let's have a function call
function doSomethingAndInvokeCallback(callback){
// do something
callback();
}
I can check if given argument is function if(typeof callback == 'function')
How can I discover, if given callback function is function and isn't empty?
like
doSomethingAndInvokeCallback(function(){
//nothing here
})
There is no totally reliable way to know if a function is empty because there are multiple kinds of functions in JS, some implemented with JS and some implemented with native code and you can't know for sure whether the function passed in does anything or not. If you want to limit the passed in function to only very simple JS functions, you could use the mechanisms outlined by other answers here (examining the source of the function). But, I would not recommend doing that in anything but a tightly controlled situation because there are lots of legal javascript ways to break that.
I would suggest that you should change the contract of your function arguments and have the caller pass null or not pass anything (which will make the argument undefined) rather than an empty function. Then, it will be very clear whether they intend to have a function called or not. If they then pass an empty function instead of null or undefined, they are getting the behavior that the interface of the function specifies. The caller can choose the desired behavior and you can implement your function in a more failsafe manner.
Also, one of your main suppositions in your question is not quite right. You cannot safely use typeof x == "function" to determine if something is a function as that will not work reliably in some older versions of IE for some types of functions. If you want to learn how to detect if something is a function at all, you can learn from jQuery here (even if you're not using it). jQuery has a function it uses internally all the time called jQuery.isFunction() that returns a bool. It uses that mostly for testing arguments to see if a function was passed.
Internally, it calls:
Object.prototype.toString.call(o)
and then examines the result. If the result has "Function" in it, then test test parameter is a function.
So, using the same technique used in jQuery, you could build your own simple little isFunction routine like this:
function isFunction(test) {
return(Object.prototype.toString.call(test).indexOf("Function") > -1);
}
Of course, if you have jQuery available, you could just use it's own version:
jQuery.isFunction(o)
When there are questions with potential cross browser compatibility issues, I find it instructional to look at how one of the big libraries solves the issue, even if you aren't going to be using that library. You can be sure that the libraries have been vetted against many browsers so a technique they are using is safe. You sometimes have to unwrap all their own internal routines they may use to figure out what they're really doing (which was the case for this function), but you can save yourself a lot of legwork.
You can see a working test bed for this here: http://jsfiddle.net/jfriend00/PKcsM/
In modern browsers typeof fn === "function", but in older versions of IE, some functions give a typeof === "object" which is probably why jQuery uses this other method which does work in those older versions of IE.
It seems that you can define a function to retrieve the body of a function(1). I wrote a small (non-definitive) test of this:
http://jsfiddle.net/6qn5P/
Function.prototype.getBody =
function() {
// Get content between first { and last }
var m = this.toString().match(/\{([\s\S]*)\}/m)[1];
// Strip comments
return m.replace(/^\s*\/\/.*$/mg,'');
};
function foo() {
var a = 1, b = "bar";
alert(b + a);
return null;
}
console.log(foo.getBody());
console.log(foo.getBody().length);
One possibility is matching the .toString result against a regexp to get the function body, and then trim to check whether it has become an empty string:
var f = function foo() {
};
/^function [^(]*\(\)[ ]*{(.*)}$/.exec(
f.toString().replace(/\n/g, "")
)[1].trim() === ""; // true
That ugly regexp does take care of spaces aroung named functions as well as extraneous spaces before the name and the opening brace. Spaces like in foo () do seem to be removed, so there is no reason to check for those.
You might be able to get this from .toString():
var blank = function(){};
var f = function(){};
var f2 = function() { return 1; };
f.toString() == blank.toString(); // true
f2.toString() == blank.toString(); // false
but this is really prone to error:
var blank = function(){};
var f = function(){ }; // extra space!
f.toString() == blank.toString(); // false
You could munge the strings a bit to try to overcome this, but I suspect this is very browser-dependent. I wouldn't actually try to do this in a production environment if I were you. Even if you normalize the whitespace, it still won't catch other no-op lines, including comments, useless var statements, etc. To actually address these issues, you'd probably need a whole tokenizer system (or a crazy regex).
You can't do it for a host function, but for others, you can fairly reliably do
function isEmpty(f) {
return typeof f === "function" &&
/^function[^{]*[{]\s*[}]\s*$/.test(
Function.prototype.toString.call(f));
}
This isn't efficient, but major interpreters implement toString for functions in such a way that it works, though it will not work on some interpreters for some empty-ish functions
function () { /* nothing here */ }
function () { ; }
function () { return; }
In some implementation you can just do a toString() on the function and get it's content. Though it contains comments etcetera.
var foo = function(){ /* Comment */ };
alert(foo.toString());
So I am getting incredible weird java script behavior inside a chrome tab. The page is behind a login so I can't post it but can someone explain exactly what is happening???
for(var z in ""){ console.log(z) }
contains
//undefined
hmm...
var key = ""
for(var i in key){ console.log(i) }
contains
//undefined
Object.getOwnPropertyNames(key)
//["length"]
Object.getOwnPropertySymbols(key)
//[]
window[key]
//undefined
At first I thought this was one of those JS behaviors and was ready to submit it to JSWTF but the behavior runs properly in another chrome tab:
for(var i in ""){ console.log('ran',i) }
//undefined
How did a value get assigned to a blank string?
Where is it?
What is the for loop doing?
edit: The same page in firefox returns expected behavior in console. I have not tested other browsers
You have an ES6 shim on the original page which adds the function contains() to the String prototype. You can do this yourself by doing something like:
String.prototype.contains =
function(e) {
return this.indexOf(e) > -1;
};
The ES6 function ultimately standardized on is includes(), so you'll probably see that function name change in the future when a developer updates the shim.
I'm new to ES6 Javascript which means i'm exploring it. I like the arrow function and default parameter feature from ES6 which is mentioned in the below site.
http://es6-features.org/#ExpressionBodies
http://es6-features.org/#DefaultParameterValues
Below is my code snippet of ES6 and i have tested this in Chrome 47. I'm trying to give default parameter value for my arrow function which is currently throwing error like
<script type="text/javascript">
'use strict';
var greet = (name = 'Venkat') => (console.log('Hi ' + name + '!'));
greet(); // expected output: Venkat
greet('Venkatraman'); // expected output: Venkatraman
</script>
Let me know whether its possible, if so, explain with solution and what i'm doing wrong here.
No, that's not possible (yet, I suppose). What you can do though:
var greet = name => console.log('Hi ' + (name || 'Venkat') + '!');
greet(); // output: Venkat
greet('Venkatraman'); // output: Venkatraman
Try it here
[jan 2018] The default parameter value is now supported in all major browsers I suppose
It seems it support only in Firefox
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters
I'm trying to alert any JavaScript object as a string, in a function. This means if the parameter given to the function is window.document, the actual object, it should alert "window.document" (without quotes) as a literal string.
The following calls...
example(window);
example(window.document);
example(document.getElementById('something'));
...calling this function...
function example(o) {/* A little help here please? */}
...should output the following strings...
window
window.document
document.getElementById('something')
I've attempted to do this with combinations of toString() and eval() among some more miscellaneous shots in the dark without success.
No need insane backwards compatibility, newer ECMAScript / JavaScript features/functions are fine. Feel free to inquire for clarifications though the goal should be pretty straight forward.
This is not possible to do in a self contained script.
If using a preprocessor would be an option, then you could write one which converts example(whatever) into example('whatever'). Other than that I'm afraid you're out of luck.
The first problem is that objects don't have names.
The second problem is that from your examples, you're not really wanting to print the (nonexistent) name of an object, you want to print the expression that evaluated into a reference to an object. That's what you're trying to do in this example:
example(document.getElementById('something'));
For that to print document.getElementById('something'), JavaScript would have had to keep the actual text of that expression somewhere that it would make available to you. But it doesn't do that. It merely evaluates the parsed and compiled expression without reference to the original text of the expression.
If you were willing to quote the argument to example(), then of course it would be trivial:
example( "document.getElementById('something')" );
Obviously in this case you could either print the string directly, or eval() it to get the result of the expression.
OTOH, if you want to try a real hack, here's a trick you could use in some very limited circumstances:
function example( value ) {
var code = arguments.callee.caller.toString();
var match = code.match( /example\s*\(\s*(.*)\s*\)/ );
console.log( match && match[1] );
}
function test() {
var a = (1);
example( document.getElementById('body') );
var b = (2);
}
test();
This will print what you wanted:
document.getElementById('body')
(The assignments to a and b in the test() function are just there to verify that the regular expression isn't picking up too much code.)
But this will fail if there's more than one call to example() in the calling function, or if that call is split across more than one line. Also, arguments.callee.caller has been deprecated for some time but is still supported by most browsers as long as you're not in strict mode. I suppose this hack could be useful for some kind of debugging purposes though.
Don't know why you need this, but you can try walking the object tree recursively and compare its nodes with your argument:
function objectName(x) {
function search(x, context, path) {
if(x === context)
return path;
if(typeof context != "object" || seen.indexOf(context) >= 0)
return;
seen.push(context);
for(var p in context) {
var q = search(x, context[p], path + "." + p);
if(q)
return q;
}
}
var seen = [];
return search(x, window, "window");
}
Example:
console.log(objectName(document.body))
prints for me
window.document.activeElement
I use Object.freeze as a means to prevent myself from breaking my own rules. I would like Object.freeze to speak to me when I try to make a bad assignment. However, Object.freeze simply makes the assignments silently fail! For example, if I do
/*
* Frozen singleton object "foo".
*/
var foo = (function() {
var me = {};
me.bar = 1;
if (Object.freeze) {
Object.freeze(me);
}
return me;
})();
foo.bar = 2;
console.log(foo.bar);
the console will log "1", but I won't know that I ever made a bad assignment. This of course can lead to dangerous unexpected behavior in my code, when the whole point of freezing the object was to avoid the unexpected. In fact, I'm more likely to get verbose error output by not freezing the object, letting the bad assignment take place, and having my code fail later on because of the bad value.
I'm wondering if JavaScript has any hidden "immutable object warning" pragma in any browser, so that I can know when I attempt to mutate an "Object.frozen" object.
Code in strict mode will throw a TypeError when trying to assign to an unwritable property (ECMA-262: 11.13.1). But do notice you cannot rely on the error being thrown in browsers that don't fully support ES5 strict mode (such as IE9).
To make your code run in strict mode, add 'use strict'; at the beginning of the JS file or function containing the code and run it in an environment that implements strict mode (see for example this list: http://caniuse.com/#feat=use-strict).
The accepted answer isn't working for me. I'm putting this in an answer because I couldn't format it clearly in a comment.
From console in Chrome 109:
> f = () => {'use strict'; const x={a:1}; return Object.freeze(x);}
() => {'use strict'; const x={a:1}; return Object.freeze(x);}
> x = f()
{a: 1}
> x.b=4 // (No warning)
4
> x
{a: 1}