jQuery objects comparison - javascript

According to the jQuery documentation, "Not All jQuery Objects are Created ===."
"An important detail regarding this "wrapping" behavior is that each wrapped object is unique. This is true even if the object was created with the same selector or contain references to the exact same DOM elements."
documentation
I know how to work around this but why is this the case? Is this some specific way that JavaScript behaves?

Yes. Every object in JS is unique, in that o1 === o2 will not be true unless o1 and o2 are pointers to the same object.
{ foo: 1 } === { foo: 1 }; // false
So jQuery objects simply follow this same rule:
var jq1 = $('.foo');
var jq2 = $('.foo');
jq1 === jq2; // false
The only exception is if you have variables that actually point to the same jQuery object:
var jq3 = jq1;
jq3 === jq1; // true

Related

Javascript Object.freeze() does not prevent changes to object

I am trying to understand the Object.freeze method of ECMAscript.
My understanding was that it essentially stops changes to all the properties of an object. MDN documentation says:
Prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed.
This does not seem to be the case, but perhaps I have misinterpreted the docs.
Here is my object, with its enumerable property exampleArray
function myObject()
{
this.exampleArray = [];
}
var obj = new myObject();
obj.exampleArray[0] = "foo";
Now if I freeze the object, I would expect the exampleArray property to be frozen too, as in it can no longer be changed in any way.
Object.freeze(obj);
obj.exampleArray[1] = "bar";
console.log(obj.exampleArray.length); // logs 2
"bar" has been added to the array, thus the frozen object has been changed. My immediate solution is to just freeze the desired property:
Object.freeze(obj.exampleArray);
obj.exampleArray[2] = "boo";
Now changing the array throws an error, as desired.
However, I am developing my application and I don't yet know what will be assigned to my object. My use case is that I have some game objects which are initialized (from an XML file) when the game starts. After this, I do not want to be able to change any of their properties accidentally.
Perhaps I am misusing the freeze method? I would like to be able to freeze the whole object, a sort of recursive freeze. The best solution I can think of here is to loop through the properties and freeze each one.
I've already searched for this question and the only answer says it's an implementation bug. I am using the newest version of Chrome. Any help is appreciated.
Object.freeze is a shallow freeze.
If you look at the description in the docs, it says:
Values cannot be changed for data properties. Accessor properties (getters and setters) work the same (and still give the illusion that you are changing the value). Note that values that are objects can still be modified, unless they are also frozen.
If you want to deep-freeze an object, here's a good recursive example
function deepFreeze(o) {
Object.freeze(o);
Object.getOwnPropertyNames(o).forEach(function(prop) {
if (o.hasOwnProperty(prop)
&& o[prop] !== null
&& (typeof o[prop] === "object" || typeof o[prop] === "function")
&& !Object.isFrozen(o[prop])) {
deepFreeze(o[prop]);
}
});
return o;
}
function myObject() {
this.exampleArray = [];
}
var obj = deepFreeze(new myObject());
obj.exampleArray[0] = "foo";
console.log(obj); // exampleArray is unchanged
Set the property descriptors for the object to writable:false, configurable:false using Object.defineProprties; then call Object.preventExtensions on the object. See How to create static array in javascript.

Two ways of determining if object has property in JavaScript

Given this object:
var myObject = {
...
};
Is this method:
var hasProp = Object.keys(myObject).indexOf('myProp') !== -1;
The same as:
var hasProp = myObject.hasOwnProperty('myProp')
That is, will they result in the same value for hasProp, always?
I was asked this in an interview and the interviewer said they would yield different results but did not give me an example.
Thanks!
Any non-enumerable property breaks this symmetry. For example, fire up a Node.js console or use a compliant browser's console to perform both:
Object.keys([]); // yields []
[].hasOwnProperty('length'); // yields true.
because for arrays, the magic length property is marked as non-enumerable. There is another function which does all of them, even non-enumerables:
Object.getOwnPropertyNames([]) // yields [ 'length' ]
that is fully equivalent.
Object.keys "returns an array of a given object's own enumerable properties". hasOwnProperty works regardless of the fact that the property is enumerable or not.
See this example where hasOwnProperty is true yet Object.keys does not contain the property.
var obj = {};
Object.defineProperty(obj, "prop", {value: 1, enumerable: false});
obj.prop; // 1
obj.hasOwnProperty("prop"); // true
Object.keys(obj); // []
Object.keys(obj).indexOf('prop'); // -1
This uses the ECMAScript 5 defineProperty but non-enumerable properties also exist on basic objects. As shown by #ChrisDrost, the array's length is a non-enumerable property that does not show up in Object.keys yet responds true to hasOwnProperty.
Your code will not always return the same value for hasOwnProperty.
From Mozilla's Documentation on hasOwnProperty:
Example: Direct versus inherited properties
The following example differentiates between direct properties and
properties inherited through the prototype chain:
o = new Object(); o.prop = 'exists'; o.hasOwnProperty('prop'); // returns true
o.hasOwnProperty('toString'); // returns false
o.hasOwnProperty('hasOwnProperty'); // returns false
Which means that your method acts as a sort of hasOwnProperty that also checks for inherited attributes.
I think in practice, they act the same, but this a subtle difference.

How to check if a property exists in an object's prototype chain?

I am a newbie in Javascript and trying to learn this language. After going through several posts I figured out that in order to check an Object's particular property we can broadly use one of the following methods.
1] Using hasOwnProperty
Object.hasOwnProperty("propertyName")
However this does not check properties inherited from the Object's prototype chain.
2] Loop over all the properties and check if property exists.
for(propertyName in myObject) {
// Check if "propertyName" is the particular property you want.
}
Using this you can check Object's properties in the prototype chain too.
My question is: Is there a method other than 2] by which I can check if "propertyName" is a property in Object's prototype chain? Something similar to "hasOwnProperty" and without looping?
You can just check the property directly with in, and it will check the prototype chain as well, like this
if ('propertyName' in myObject)
an example
var obj = function() {};
obj.prototype.test = function() {};
var new_obj = new obj();
console.log( 'test' in new_obj ); // true
console.log( 'test22222' in new_obj ); // false
console.log( new_obj.hasOwnProperty('test') ); // false
FIDDLE
Reflect.has can make a work for you
console.log(Reflect.has({}, 'toString')); // true

Detecting if a Property of an Object is an Object

I'm going to use JSON to stringify the value of a property of an object in order to store it as a Tag on Google Calendar through Google Apps Script. The value is actually a double-nested Object (see extraAttributes in myObject).
I have an Object that is built like the following:
var myObject = {
"location": "somwehere",
"date": new Date(),
"numSomething": 20,
"extraAttributes": {"used": true, "interval": 60, "internals": {"timer": 10, "visible": false} }
}
I tried to make it pretty and readable... anyway: myObject actually has anywhere from 20-40 properties, some of which are nested Objects. So here's the question:
Is there a way to notify if the value of a property in an Object is an object itself (would extra levels of nesting be an issue for this detection?)? The reasoning behind this is that I don't know how JSON.stringify and JSON.parse will affect the other data (I've tested it on that one particular value of type Object and it worked fine), and also that I don't know how much of a performance impact that those two functions would have on my script if the properties being stored reach 20-40.
I would rather do a check to see if the value is an Object and stringify only that (would that also be inefficient?). Feel free to lecture me on Objects and nesting if this would cause major problems in the future ;)
All Javascript values, except functions and undefined, can be serialized as JSON.
To answer your question, see the typeof operator.
Another way to check if something is an object instead of using typeof (which can be misleading in some cases — for example typeof [] === 'object') is to use the Object constructor:
var foo = { id: 1 };
var bar = 'string';
console.log(foo === Object(foo)) // true
console.log(bar === Object(bar)) // false

IN javascript,why {}!==Object()?

Given
var o = {};
var p = new Object();
p === o; //false
o.__proto__===p.__proto__ // true
why is this false?
please tell me the immediate reason to return false??
The === for objects is defined as:
11.9.6 The Strict Equality Comparison Algorithm
The comparison x === y, where x and y are values, produces true or
false. Such a comparison is performed as follows:
...
7. Return true if x and y refer to the same object. Otherwise, return
false.
In this case, although both are empty objects, they are created separately and hence do not refer to the same object.
As a side note, both constructions do the same thing; but it is common practice to use {}.
The two objects contain the same thing (i.e. nothing) but they are not the same object.
Javascript's object equality test requires that the two parameters refer to the exact same object.
JavaScript strict comparison for objects tests whether two expressions refer to the same objects (and so does the normal equals operator).
You create the first object using object literal {} which creates a new object with no properties.
You create the second object by calling Object constructor as a function. According to section 15.2.1.1 of ECMAScript Language Specification this also creates a new object just as if new Object() was used.
Thus you create two objects, store their references under p and o and check whether p and o refer to the same object. They don't.
Every time you create an object, the result has its own, distinct identity. So even though they are both "empty", they are not the same thing. Hence the === comparison yields false.
Using the === , the result will show if items on both side is the "Same Instance"
If you like to comparing two item are same type, you should use:
var o1 = {};
var o2 = new Object();
alert( typeof(o1) === typeof(o2));
and if you like to tell if the two object is considered equal (in properties and values), you should try underscore.js library and use the isEqual function.
Is this homework?
In that case, I will only give you some hints:
- Think about what the first two lines do. Do o and p refer to the same object after those two lines?
- Look up exactly what === does. Does it compare two objects to see if their structure are the same? Or does it compare the objects based on their identity?
Object is an unordered collection of properties each of which contains a primitive value, object, or function. So, each object has properties and prototypes and there's no any sense to compare the one.

Categories

Resources