This question already has answers here:
Legitimate uses of Object(o)
(2 answers)
Closed 8 years ago.
Snippet from underscore.js for testing object
_.isObject = function(obj) {
return obj === Object(obj);
};
What exactly is this doing that makes it check for the type?
A jsperf shows that this is faster than using a conventional check, that is why it is used.
The Object constructor creates an object wrapper for the given value. If the value is null or undefined, it will create and return an empty object, otherwise, it will return an object of a type that corresponds to the given value.
Source
What does Object(obj) do?
Read the EcmaScript spec on The Object Constructor Called as a Function and the abstract ToObject operation.
What exactly is this doing that makes it check for the type?
Object(obj) will only yield an object that is strictly equal (===) to obj (i.e the same reference as the input) when the input was a non-primitive value (null, booleans, strings, numbers, undefined), i.e. an EcmaScript Object (including String/Boolean/Number/Array instances, functions, other objects).
I can't find the relevant documentation, but it appears that the Object function either returns a new object that wraps the passed in value or returns the argument if it's already an object; otherwise, the === test would always return false.
Object(5) === 5 // false, Object(5) creates Number object
Object(null) === null // false, Object(null) creates an empty object
var foo = { prop: 'value' };
Object(foo) === foo // true!? Argument is not wrapped
It appears that this behavior works to test if a value is an object.
Update
It appears that this is in the spec:
When the Object function is called with no arguments or with one argument value, the following steps are taken:
1. If value is null, undefined or not supplied, create and return a new Object object exactly as if the standard built-in Object constructor had been called with the same arguments (15.2.2.1).
2. Return ToObject(value).
And ToObject's "result is the input object" is also defined in the spec.
Related
This question already has answers here:
Why, in JavaScript, does '3 instanceof Number' == false, but '3..method()' will call Number.prototype.method?
(1 answer)
javascript: do primitive strings have methods?
(2 answers)
Why does a primitive variable act like an Object? [duplicate]
(3 answers)
How does JavaScript .prototype work?
(26 answers)
Closed 2 years ago.
There was zero explanation about this in the book I'm reading. They just threw an example with this, and didn't bother to explain anything at all.
I keep testing and experimenting with this in an attempt to infer what it is and how it works exactly, and most of all, how is this different from just creating a new variable and then assigning a function to it.
Is the only difference just the fact that, you can use 'this' keyword with the String.prototype, because the String variable to which it has to be attached to becomes the parent object?
What I don't get it, what exactly are you creating? Are you creating a new method? Property? value? Just a function that can contain a value or some statement to be executed, and then you assign that function to .. a new String? Why do I need to assign the new function to a String in order to run it? If I just target the name of the function, it won't work. It has to attached to a String variable to execute the function. Why?
String.prototype.more = function() {
var confirm2 = 2 + 2;
return confirm2;
}
alert(more());
I can't create a new function and then try to run it without either writing the whole name "String.prototype.more()", or first creating a new variable, and then attaching the name "more" to it, and then the function is triggered.
Can somebody explain to me does String.prototype.something = function() {} create a new function and assign it to the 'something', and it could just contain a retuned value or a statement waiting to get executed? If so, how is this different from just creating a new variable and doing the same thing? Is the only difference the fact that you can use 'this' keyword? Why do I need to attach the function name to a String in order to run it? Am I not understanding something important here?
you can Use the prototype property to add a new property to all objects of a given type ,
in your example you are trying to add new property to the string type :
String.prototype.more = function() {
var confirm2 = 2 + 2;
return confirm2;
}
alert('example'.more());
//that will allert 4
JavaScript is a little weird in some aspects compared to other programming language.
JavaScript functions are full objects. In other languages functions are language constructs. For example if you create a function like this
function example1() {}
what you are really doing is creating an object of type function to the root object (which is the window object in your browser)
function example1() {}
console.log(window.example1) // function example1() {}
console.log(typeof window.example1) // function
Every object template in JavaScript has a prototype. So when you want to check for a function or a value of an object (hence called property), and that object doesn't have that property, JavaScript examines the prototype of that object, if the property is there. If that is not the case, JS will climb up the prototype ladder until it finds that property or reaches the end of the ladder (which is the object template)
In your case: String is the template object, if you create a string
// A is created as a new String
A = "a"
// The constructor of string is the String object which is a native function
console.log(String) // function String() { [native code] }
console.log(typeof String) // function
console.log(A.constructor === String) // true
// The String function has a prototype which contains all the functions of the String "class"
console.log(String.prototype) // function
// The method `sub` of the A object is in fact the method `sub` of the `String.prototype`
// that means A doesn't have the method sub for itself, but uses the
console.log(A.sub === String.prototype.sub) // true
// There are some other wild things going on that include `__proto__` and `constructor` properties.
console.log(String.prototype.__proto__.constructor === Object) // true
Regarding your case
String.prototype.more = function() {
var confirm2 = 2 + 2;
return confirm2;
}
a = "" // `a` is created as string has now a __proto__ property that points to String.prototype
// Following three are all the same
console.log(a.more) // more doesn't exist, but the more method of the prototype is used
console.log(a.__proto__.more) // `a.__proto__` is a reference to `String.prototype`
console.log(String.prototype.more)
Edit 1
Some more general examples
console.clear()
a = new Object()
// a now has automatically been assigned a `constructor` property, which is the `Object` function
console.log(a.constructor) // function Object()
// the Object function has a `prototype` property, which is an object
console.log(typeof Object.prototype) // object
// a is assigned a `__proto__` property, which is a reference to the `prototype` property of its `constructor`
console.log(a.__proto__ === a.constructor.prototype) // true
// a has inherited a method `hasOwnProperty` which tells us, if a property is directly on the object or is inherited from the prototype chain
console.log(a.hasOwnProperty('myNewProperty')) // false
a.myNewProperty = 'this is my own'
console.log(a.hasOwnProperty('myNewProperty')) // true
// Here you can see: `a` doesn't have the property `hasOwnProperty`, but the `__proto__` (which is `Object.prototype`) has
console.log(a.hasOwnProperty('hasWonProperty')) // false
console.log(a.__proto__.hasOwnProperty('hasOwnProperty')) // true
This question already has answers here:
Applying a Function to Null in Javascript
(5 answers)
Closed 7 years ago.
I am learning about call and apply in javaScript from a online TUT. This function allows more arguments to be passed, rather than having a fixed amount.
var calculate = function(){
var fn = Array.prototype.pop.apply(arguments);
return fn.apply(null, arguments);
};
What I am having difficulty wrapping my head around is this statement.
var fn = Array.prototype.pop.apply(arguments);
The presenter of the of the TUT, explained it as the following:
We are binding the apply method onto the arguments object. This is going to give us the Function Object and assign it to the fn variable. It will also remove the Function Object from the argumentsObject. Because the Array's pop method takes the final element in the array, it removes it from the Array and then assigns to what ever called the method. In this case the fn variable.
What confused me was the following:
We are binding the apply method onto the arguments object. This is
going to give us the Function Object
It will also remove the Function Object from the arguments
Object.
And when we write in the return statement:
return fn.apply(null, arguments);
Why are we including null?
Array.prototype.pop.apply(arguments);
When you have a function, there's automatically an arguments objects, which is an Array-like object of arguments. If you call this fake function:
someFunction('hello', 'world');
and someFunction looks like this:
function someFunction() {
console.log(arguments);
}
The console.log will output ['hello', 'world']. However, don't be confused... That is not an Array object! It is an "array-like" object. Therefore, you can't say arguments.pop()... because arguments doesn't have that method (it belongs to Array.prototype). However, normal Array objects do have access to Array.prototype (e.g. [1,2,3].pop() // => [1,2]).
When you say .apply(), the first argument is the context... It sets the this. So really, Array.prototype.pop.apply(arguments) is a clever way of mimicking arguments.pop(). But you can't do arguments.pop(), because it doesn't have a pop method.
In return fn.apply(null, arguments);, null is the first arguments because we don't need to set a new context for this example. arguments is the second arguments because it's being passed in to use with fn.
.apply() returns a function object, so it returns something like this:
function() { ... }
We can then later invoke that function.
By the way, .pop() mutates the original object (in this case, the array-like object arguments). So you're passing in arguments to fn, but it's missing the last item that was in it previously.
According to MDN:
Syntax
fun.apply(thisArg, [argsArray])
Parameters
thisArg:
The value of this provided for the call to fun. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode code, null and undefined will be replaced with the global object, and primitive values will be boxed.
argsArray:
An array-like object, specifying the arguments with which fun should be called, or null or undefined if no arguments should be provided to the function. Starting with ECMAScript 5 these arguments can be a generic array-like object instead of an array. See below for browser compatibility information.
The last argument passed to calculate is assumed to be a function. It is popped from the arguments list. (Using apply because arguments is not a real array.)
This popped function (fn) is called with the rest of the arguments list. (All other arguments passed to calculate). The arguments list no longer contains fn because pop() modifies the original object.
NULL is used because fn is called without a value for this. (See MDN)
If you call calculate for instance like
calculate(2, 3, function(a, b){ return a + b });
it will return 5.
This question already has answers here:
new Number() vs Number()
(5 answers)
Closed 9 years ago.
I'm trying to understand the difference between writing m = Number() (which causes typeof m to evaluate as "number") vs m = new Number() (which causes typeof m to evaluate as "object").
I would have expected it to be an object either way. I was just messing around, and I added a .helloWorld() method to the Number prototype, and I was able to access it on m regardless of which method I used to instantiate it.
What's the difference here? What am I doing differently between writing Number() and new Number()? Why is one an object while the other is a number?
Number() by itself returns a number primitive. When you call new Number() you receive a new instance of an Object which represents Number's (relevant ES5 spec).
When you call a property on a primitive, the primitive is auto-boxed (like in Java) to an instance of that object, which is what lets you call helloWorld() on either the object or number.
However, try this;
var x = Number(5);
x.bar = function (x) { alert(x); };
x.bar("hello");
var y = new Number(5);
y.bar = function (x) { alert(x); };
y.bar("hello");
You'll see the latter works whilst the former does not; in the first, the number is autoboxed to a number, and the bar method is added to it (the object). When you call x.bar() you're creating a new auto-boxed Number, which bar doesn't exist on.
In the latter, you're adding a bar method to that Number instance, which behaves like any other Object instance, and therefore it persists throughout the lifetime of the object.
This is just how it is implemented. This particular constructor function, when called without new, returns a primitive number. When called with new, it returns the object-wrapped number.
You can access prototype methods/properties on primitives because behind the scenes, JavaScript converts them to objects, calls the prototype method, and then throws away the object copy. This allows you to do things like:
var myString = "foo";
console.log( myString.length ); //=> 3
console.log( typeof myString ); //=> "string"
An object copy of the primitive gets made on line two, the length property of the object is checked, and then the object copy is thrown away. myString stays as a string primitive.
I'm in ES5 strict mode, so the solution
function isArguments(item) {
return item.callee !== undefined;
}
unfortunately doesn't work.
function isArguments( item ) {
return Object.prototype.toString.call( item ) === '[object Arguments]';
}
William's answer is right, but some explanations may be useful.
In ECMAScript 5, the only thing that characterizes Arguments objects is their internal [[Class]], as seen in §10.6 Arguments Object:
When CreateArgumentsObject is called the following steps are
performed:
Let obj be the result of creating a new ECMAScript object.
Set the [[Class]] internal property of obj to "Arguments".
Return obj
[[Class]] is an internal property common to all objects, whose value is a String which classifies the object. This is explained in §8.6.2 Object Internal Properties and Methods:
The value of the [[Class]] internal property is defined by this
specification for every kind of built-in object.
The value of a [[Class]] internal property is used internally to
distinguish different kinds of objects.
Moreover, note that host objects won't be problematic:
The value of the [[Class]] internal property of a host object may be
any String value except one of "Arguments", [...]
Therefore, to identify an Arguments object you only need to check its class.
You can do that using §15.2.4.2 Object.prototype.toString:
Let O be the result of calling ToObject passing the this value as the argument.
Let class be the value of the [[Class]] internal property of O.
Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
Therefore, you can use Function.prototype.call to call that method with the this value set to the object you want to check. The returned string will be '[object Arguments]' if, and only if, it's an Arguments object.
Object.prototype.toString.call(obj) == '[object Arguments]'
Note that isn't completely foolproof, because the global Object could have been shadowed by a local one, or the global Object or its toString property could have been modified.
However, there is no better way:
Note that this specification does not provide any means for a program
to access that value except through Object.prototype.toString (see
15.2.4.2).
Generating and comparing strings to determine the type of an object is a little fuzzy. Like #bergi suggested, I think Lodash is doing it a more convenient way. Condensed into one function it is:
function isArguments(value) {
return !!value && typeof value == 'object' && Object.prototype.hasOwnProperty.call(value, 'callee') && !Object.prototype.propertyIsEnumerable.call(value, 'callee');
}
See http://jsfiddle.net/FDhQF/1/ for a trivial example.
What's the difference between something being undefined and something not being defined in Javascript? For instance, trying to access a property for an object (effectively, trying to access a variable) that isn't defined will return undefined. But you can also set something = undefined. When you do that, trying to access it still return undefined, but the pointer is still there. An example, as above, is how iterating over an object still goes over the property that you've (re)declared as undefined. It seems like there are two different sorts of undefined. Can anyone shed some light on the situation?
Both, accessing a property that isn't defined on an object and a property that contains the primitive undefined value, will return you undefined.
For example:
var obj = {
a: undefined
};
obj.a; // undefined
obj.b; // undefined
The difference is that a is an own property, and b isn't:
obj.hasOwnProperty('a'); // true
obj.hasOwnProperty('b'); // false
In the first case a is an own property, even if it contains undefined as its value. In the second case, b is not an own property, accessing obj.b will look for a property named b, all way up in the prototype chain.
When the prototype chain ends (when it reaches an object with a null [[Prototype]]), the property lookup ends and undefined is explicitly returned.
You should know that the hasOwnProperty method checks only if the property physically exist on the object (own properties), but we have also inherited properties, for that case we can use the in operator, for example:
function Test () {}
Test.prototype.a = 'foo'; // instances of Test will inherit from Test.prototype
var obj = new Test(); // { a="foo", b="bar"}
obj.b = 'bar';
obj.hasOwnProperty('a'); // false
'a' in obj; // true
obj.a; // 'foo'
obj.hasOwnProperty('b'); // true
As you can see, obj inherits from Test.prototype, and the a property is not an own property, but it is available through the prototype chain. That's why hasOwnProperty returns false and the in operator returns true.
You can see how internally properties are resolved by the [[Get]] internal operation
Notes:
Accessing undefined as an identifier is not considered to be safe on ECMAScript 3 (the most widely implemented version of the language standard), because instead of being a language keyword (such as null for example) is just a property of the global object, and it is writable on this version of the Spec., meaning that if someone replaces its value (e.g. window.undefined = 'LOL';) , it will break your code.
The typeof operator as #strager mentions can be used instead, for example:
if (typeof obj.prop == 'undefined') { /*....*/ }
This operator returns always a string (it's safe to use == :), and its value depends of the type of its operand, the possible values are described here.
Another common way to solve this is to declare your own undefined variable, available on the scope of your functions, for example, some libraries use the following pattern:
(function(undefined) {
// code here
})();
The function has an argument named undefined, and it is executed immediately without passing any value to it (the last pair or parens make the invocation).
Maybe is worth mentioning that the undefined global property was finally described on ECMAScript 5 as non-writable (immutable, as well non-enumerable and non-configurable -non deletable-).
Using the hasOwnProperty method directly from an object instance is also not considered as safe, because if some object has a property with the same name, the original method will be shadowed. For example:
var obj = { hasOwnProperty: function () { /* evil code :) */ } };
If you call:
obj.hasOwnProperty('prop');
The method defined on the object will be executed (and you wouldn't want this since you know exactly which method you want to invoke...), because it shadows the one from the Object.prototype, however it can be safely invoked by:
Object.prototype.hasOwnProperty.call(obj, 'prop');
Here is a good explanation of "undefined". The gist however is that setting something to "undefined" is not UN-defining it, because "undefined" is actually a primitive value, which is used when a variable (or property) has not been assigned a value.