This question already has an answer here:
Why is my JavaScript hoisted local variable returning undefined but the hoisted global variable is returning blank? [duplicate]
(1 answer)
Closed 6 years ago.
var name = new String("green");
console.log(name instanceof String);//returns false
var color= new String("green");
console.log(color instanceof String);//returns true
Here the first one is returning false and the second one is returning true,what is the reason if i use variable as name it showing false
and are there are any variables like name which throws error as happened with variable name
Since name is reserved keywrd in javascript (not really reserved but global object), it directly points to window.name
you can try _name and it will work
var _name = new String("green");
console.log(_name instanceof String);//returns true
This is because you are trying to overwrite the global name variable, which has a setter that automatically converts anything you assign to it to a string (new String creates a String object, which is not the same as a string).
The solution: use a different variable name or properly scope your variables.
console.log(typeof name); // string
var name = new String("green");
console.log(typeof name); // still string
var color = new String("green");
console.log(typeof color); // object
// create new scope
function myFunction() {
var name = new String("green");
console.log(typeof name); // object
var color = new String("green");
console.log(typeof color); // object
}
myFunction();
The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.
In the first case it checks the prototype chain find it undefined and return false. This is not only with name but following example will also return false
var simpleStr = 'This is a simple string';
console.log(simpleStr instanceof String);
An alternative way is to test it using typeof or constructor
The same example will return true for the following case
var simpleStr = 'This is a simple string';
simpleStr .constructor == String
For your example also if you do
var name = new String("green");
name .constructor == String
it will return true
Related
In JavaScript is there any difference between using String() and new String()?
console.log(String('word')); // word
console.log(new String('word')); // word
Using the String() constructor without new gives you the string (primitive) value of the passed parameter. It's like boxing the parameter in a native object if necessary (like a Number or Boolean), and then calling .toString() on it. (Of course if you pass a plain object reference it just calls .toString() on that.)
Calling new String(something) makes a String instance object.
The results look the same via console.log() because it'll just extract the primitive string from the String instance you pass to it.
So: just plain String() returns a string primitive. new String(xyz) returns an object constructed by the String constructor.
It's rarely necessary to explicitly construct a String instance.
String() returns a string primitive and new String() returns a Object String. This has some real consequences for your code.
Using String() returns 'true' with other primitives both with == and === operator.
Using String() gives you a primitive so it cannot use the "instanceOf" method to check its type. You can check only value type with "typeof" operator
Using new String() with "instanceOf" method with String or Object prototypes - both assert to true.
Using new String() will return 'true' with string primitives only by calling valueOf() method. String() has also this method and returns true when compared to string of the same value.
Using new String() allows you to add some other properties and methods to the Object to allow more complex behaviour.
From my coding experience you should avoid using new String() if you have no need for adding special methods to your String Object.
var x = String('word');
console.log(typeof x); // "string"
var y = new String('word');
console.log(typeof y); // "object"
// compare two objects !!!
console.log(new String('') === new String('')) // false!!!
// compare with string primitive
console.log('' == String('')) // true
console.log('' === String('')) // true
//compare with string Object
console.log('' == new String('')) // true
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
console.log('' === new String('')) // false !!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// instance of behavior
console.log(x instanceof String); // false
console.log(x instanceof Object); // false
// please note that only new String() is a instanceOf Object and String
console.log(y instanceof String); // true
console.log(y instanceof Object); // true
//valueOf behavior
console.log('word' == x.valueOf()); // true
console.log('word' === x.valueOf()); // true
console.log('word' == y.valueOf()); // true
console.log('word' === y.valueOf()); // true
//create smart string
var superString = new String('Voice')
superString.powerful = 'POWERFUL'
String.prototype.shout = function () {
return `${this.powerful} ${this.toUpperCase()}`
};
console.log(superString.shout()) //"POWERFUL VOICE"
Strings returned from String calls in a non-constructor context (i.e., without using the new keyword) are primitive strings.
Strings created with new String() (constructor mode) is an object and can store property in them.
Demonstrating the difference:
var strPrimitive = String('word');
strPrimitive.prop = "bar";
console.log(strPrimitive.prop); // undefined
var strObject = new String('word');
strObject.prop = "bar";
console.log(strObject.prop); // bar
Here is an example in addition to the good answers already provided:
var x = String('word');
console.log(typeof x); // "string"
var y = new String('word');
console.log(typeof y); // "object"
The exact answer to your question is here in the documentation.
String literals (denoted by double or single quotes) and strings
returned from String calls in a non-constructor context (i.e., without
using the new keyword) are primitive strings.
Generally it's not recommended to use constructor functions (i.e. using new keyword) because it can lead to unpredictable results.
For example:
if (new Number(0)) { //
console.log('It will be executed because object always treated as TRUE in logical contexts. If you want to treat 0 as falsy value then use Number(0)')
}
Also, as mentioned above, there is another potential problem:
typeof 0; // number
typeof Number(0) // number
typeof new Number(0) // object
What are the exact circumstances for which a return statement in Javascript can return a value other than this when a constructor is invoked using the new keyword?
Example:
function Foo () {
return something;
}
var foo = new Foo ();
If I'm not mistaken, if something is a non-function primitive, this will be returned. Otherwise something is returned. Is this correct?
In other words, what values can something take to cause (new Foo () instanceof Foo) === false?
The exact condition is described on the [[Construct]] internal property, which is used by the new operator:
From the ECMA-262 3rd. Edition Specification:
13.2.2 [[Construct]]
When the [[Construct]] property for a Function object F is
called, the following steps are taken:
Create a new native ECMAScript object.
Set the [[Class]] property of Result(1) to "Object".
Get the value of the prototype property of F.
If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as
described in 15.2.3.1.
Invoke the [[Call]] property of F, providing Result(1) as the this value and
providing the argument list passed into [[Construct]] as the
argument values.
If Type(Result(6)) is
Object then return Result(6).
Return Result(1).
Look at steps 7 and 8, the new object will be returned only if the
type of Result(6) (the value returned from the F constructor
function) is not an Object.
Concrete examples
/*
ECMA 262 v 5
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
"4.3.2
primitive value
member of one of the types Undefined, Null, Boolean, Number, Symbol, or String as defined in clause 6"
*/
var Person = function(x){
return x;
};
console.log(Person.constructor);
console.log(Person.prototype.constructor);
console.log(typeof(Person));
console.log(typeof(Person.prototype));
function log(x){
console.log(x instanceof Person);
console.log(typeof x);
console.log(typeof x.prototype);
}
log(new Person(undefined));
log(new Person(null));
log(new Person(true));
log(new Person(2));
log(new Person(""));
//returns a function not an object
log(new Person(function(){}));
//implementation?
//log(new Person(Symbol('%')));
I couldn't find any documentation on the matter, but I think you're correct. For example, you can return new Number(5) from a constructor, but not the literal 5 (which is ignored and this is returned instead).
As a side note, the return value or this is just part of the equation.
For example, consider this:
function Two() { return new Number(2); }
var two = new Two;
two + 2; // 4
two.valueOf = function() { return 3; }
two + 2; // 5
two.valueOf = function() { return '2'; }
two + 2; // '22'
As you can see, .valueOf() is internally used and can be exploited for fun and profit. You can even create side effects, for example:
function AutoIncrementingNumber(start) {
var n = new Number, val = start || 0;
n.valueOf = function() { return val++; };
return n;
}
var auto = new AutoIncrementingNumber(42);
auto + 1; // 43
auto + 1; // 44
auto + 1; // 45
I can imagine this must have some sort of practical application. And it doesn't have to be explicitly a Number either, if you add .valueOf to any object it can behave as a number:
({valueOf: function() { return Math.random(); }}) + 1; // 1.6451723610516638
You can exploit this to make an object that always returns a new GUID, for instance.
Trying to put a few points in simpler words.
In javascript, when you use a new keyword on a function and if,
function does not return anything, it will return an intended object
function User() {
this.name = 'Virat'
}
var user = new User();
console.log(user.name); //=> 'Virat'
function returns any truthy complex object [object, array, function etc], that complex object takes priority and user variable will hold the returned complex object
function User() {
this.name = 'Virat';
return function(){};
}
var user = new User();
console.log(user.name); //=> undefined
console.log(user); //=> function
function returns any literal, constructor takes priority and it will return an intended object
function User() {
this.name = 'Virat';
return 10;
}
var user = new User();
console.log(user.name); //=> 'Virat'
When you are using the new keyword, an object is created. Then the function is called to initialise the object.
There is nothing that the function can do to prevent the object being created, as that is done before the function is called.
This question already has answers here:
What's the point of new String("x") in JavaScript?
(9 answers)
Closed 7 years ago.
I'm very confused about what the wrapper objects for primitives. For example, a string primitive and a string created with the string wrapper object.
var a = "aaaa";
var b = new String("bbbb");
console.log(a.toUpperCase()); // AAAA
console.log(b.toUpperCase()); // BBBB
console.log(typeof a); // string
console.log(typeof b); // object
Both give access to String.prototype methods, and seem to act just like a string literal. But one is not a string, it's an object. What is the practical difference between a and b? Why would I create a string using new String()?
A primitive string is not an object. An object string is an object.
Basically, that means:
Object strings are compared by reference, not by the string they contain
"aaa" === "aaa"; // true
new String("aaa") === new String("aaa"); // false
Object strings can store properties.
function addProperty(o) {
o.foo = 'bar'; // Set a property
return o.foo; // Retrieve the value
}
addProperty("aaa"); // undefined
addProperty(new String("aaa")); // "bar"
Does anyone know what is test[name] mean?
function test(value){
copy(value||{},this);
}
test[name] = function(){
return "test"
}
This will be easiest to explain with an example:
var name = "foo";
test[name] = function(){
return "test"
};
This would add a property named "foo" to the object test, and the value of that property is a function. It doesn't matter in this case that the object test is actually a function, you can assign properties to functions just like any other object in JavaScript.
You could call this function using any of the following methods:
test[name]()
test["foo"]()
test.foo()
Note that test[name]() will not work if the name variable is assigned to something different, for example name = 'bar'.
Javascript has two sets of notation for accessing objects, dot notation (obj.property) and bracket notation (object[property]). More on that at MDN.
test[name] = function (){} assigns an anonymous function to the name property on the the test object (which itself is a function). In this case (as noted by the comments) the variable name is being used to access the property.
This may seem a little strange at first, but it's helpful to remember that in javascript, functions are objects.
All functions in Javascript are also objects. This adds a property to the test function object with a value which is an anonymous function.
For example:
function test(){
return "foo";
}
// test is a function, so it is also an object and
// it can have properties assigned to it
test.x = function(){
return "bar";
};
test(); // "foo"
test.x(); // "bar"
Of course just like with any object you can also use bracket notation:
var name = 'hello';
test[name] = function(){
return "HELLO!";
};
test.hello(); // "HELLO!"
In JavaScript, functions are objects. They have properties. test[name] sets a property (named whatever the name variable holds) to a function.
when you have a javascript object with defined properties you can access the property either with the dot notation obj.property or with the square brackets notation obj[property]
the property could also be a function so if you have an object:
var test = {
foo : function(arg){ console.log(arg) },
bar : 'hello'
};
you can call test.foo('bar') also by doing test['foo']('bar')
This is especially useful in iterations or when you dont know a priori what the name of the property is going to be. For example:
var fun = 'foo';
test[fun]('hello world');
Naturally it's up to you to do proper checks such as
if ('function'==typeof test['foo']){ test['foo']('bar'); }
Also note that you can do checks on the fly like so:
test[ fun || 'foo']('hello');
Taken from the Mozilla page
One can think of an object as an associative array (a.k.a. map, dictionary, hash, lookup table). The keys in this array are the names of object members
There are two ways to access object members: dot notation and bracket notation (a.k.a. subscript operator).
So
test[name] = function (
means: there are (if everything is ok) two objects: test and name (and we know that at least test is present, because you defined it one line before: function test(value))
take the test object (if there isn't a test object an error will happen). Then access the key/value pair with the key calculated from the name object and there put a function.
Now, how the key is calculated from the name object? The same page from before tells us:
Property names must be strings. This means that non-string objects cannot be used as keys in the object. Any non-string object, including a number, is typecasted into a string via the toString method.
Note that the description is a little wrong... test[null] == test["null"] and test[undefined] == test["undefined"], so perhaps the truth is that under the covers something like String(key).valueOf() is done (the String function will convert null to "null" and undefined to "undefined")
Some examples (where => means "is equivalent to, with this values")
var name = 'foo';
test[name] => test['foo']
var name = 123;
test[name] => test['123']
var name = 123.3;
test[name] => test['123.3']
var name = new Date();
test[name] => test['Wed Aug 14 2013 17:35:35 GMT+0200 (...)']
var name = null;
test[name] => test['null']
var name = undefined;
test[name] => test['undefined']
var name = [];
test[name] => test['']
var name = [1,2,3];
test[name] => test['1,2,3']
var name = {};
test[name] => test['object Object']
and so on...
The brackets are how you reference a property via a key into the hash that javascript objects are.
I've got a feeling this might not be possible, but I would like to determine the original variable name of a variable which has been passed to a function in javascript. I don't know how to explain it any better than that, so see if this example makes sense.
function getVariableName(unknownVariable){
return unknownVariable.originalName;
}
getVariableName(foo); //returns string "foo";
getVariableName(bar); //returns string "bar";
This is for a jquery plugin i'm working on, and i would like to be able to display the name of the variable which is passed to a "debug" function.
You're right, this is very much impossible in any sane way, since only the value gets passed into the function.
This is now somehow possible thanks to ES6:
function getVariableName(unknownVariableInAHash){
return Object.keys(unknownVariableInAHash)[0]
}
const foo = 42
const bar = 'baz'
console.log(getVariableName({foo})) //returns string "foo"
console.log(getVariableName({bar})) //returns string "bar"
The only (small) catch is that you have to wrap your unknown variable between {}, which is no big deal.
As you want debugging (show name of var and value of var),
I've been looking for it too, and just want to share my finding.
It is not by retrieving the name of the var from the var but the other way around : retrieve the value of the var from the name (as string) of the var.
It is possible to do it without eval, and with very simple code, at the condition you pass your var into the function with quotes around it, and you declare the variable globally :
foo = 'bar';
debug('foo');
function debug(Variable) {
var Value = this[Variable]; // in that occurrence, it is equivalent to
// this['foo'] which is the syntax to call the global variable foo
console.log(Variable + " is " + Value); // print "foo is bar"
}
Well, all the global variables are properties of global object (this or window), aren't they?
So when I wanted to find out the name of my variables, I made following function:
var getName = function(variable) {
for (var prop in window) {
if (variable === window[prop]) {
return prop;
}
}
}
var helloWorld = "Hello World!";
console.log(getName(helloWorld)); // "helloWorld"
Sometimes doesn't work, for example, if 2 strings are created without new operator and have the same value.
Global w/string method
Here is a technique that you can use to keep the name and the value of the variable.
// Set up a global variable called g
var g = {};
// All other variables should be defined as properties of this global object
g.foo = 'hello';
g.bar = 'world';
// Setup function
function doStuff(str) {
if (str in g) {
var name = str;
var value = g[str];
// Do stuff with the variable name and the variable value here
// For this example, simply print to console
console.log(name, value);
} else {
console.error('Oh snap! That variable does not exist!');
}
}
// Call the function
doStuff('foo'); // log: foo hello
doStuff('bar'); // log: bar world
doStuff('fakeVariable'); // error: Oh snap! That variable does not exist!
This is effectively creating a dictionary that maps variable names to their value. This probably won't work for your existing code without refactoring every variable. But using this style, you can achieve a solution for this type of problem.
ES6 object method
In ES6/ES2015, you are able to initialize an object with name and value which can almost achieve what you are trying to do.
function getVariableName(unknownVariable) {
return Object.keys(unknownVariable)[0];
}
var foo = 'hello';
var output = getVariableName({ foo }); // Note the curly brackets
console.log(output);
This works because you created a new object with key foo and value the same as the variable foo, in this case hello. Then our helper method gets the first key as a string.
Credit goes to this tweet.
Converting a set of unique variable into one JSON object for which I wrote this function
function makeJSON(){ //Pass the variable names as string parameters [not by reference]
ret={};
for(i=0; i<arguments.length; i++){
eval("ret."+arguments[i]+"="+arguments[i]);
}
return ret;
}
Example:
a=b=c=3;
console.log(makeJSON('a','b','c'));
Perhaps this is the reason for this query
I think you can use
getVariableName({foo});
Use a 2D reference array with .filter()
Note: I now feel that #Offermo's answer above is the best one to use. Leaving up my answer for reference, though I mostly wouldn't recommend using it.
Here is what I came up with independently, which requires explicit declaration of variable names and only works with unique values. (But will work if those two conditions are met.)
// Initialize some variables
let var1 = "stick"
let var2 = "goo"
let var3 = "hello"
let var4 = "asdf"
// Create a 2D array of variable names
const varNames = [
[var1, "var1"],
[var2, "var2"],
[var3, "var3"]
]
// Return either name of variable or `undefined` if no match
const getName = v => varNames.filter(name => name[0] === v).length
? varNames.filter(name => name[0] === v)[0][1]
: undefined
// Use `getName` with OP's original function
function getVariableName(unknownVariable){
return getName(unknownVariable)
}
This is my take for logging the name of an input and its value at the same time:
function logVariableAndName(unknownVariable) {
const variableName = Object.keys(unknownVariable)[0];
const value = unknownVariable[variableName];
console.log(variableName);
console.log(value);
}
Then you can use it like logVariableAndName({ someVariable })