Memory Usage/Garbage Collection of Objects Passed Into Functions - javascript

When an object is passed into a function, the object is passed by value (although the value for an object is a reference). I am passing very large objects into my functions, but only accessing a handful of properties (6-12) from within the function. Memorywise, would it be better to only pass the properties instead of the whole object? Or would this actually create more of a memory issue if my properties are strings?
Given the two functions below, what happens memorywise? In f1, does javascript/v8 create a new object foo in memory or is it really just a pointer? Does it remain just a pointer if I access a string property or does V8 then make a copy of that string for use within the function. In f2, I assume that a completely new copy of the string foo is made for the function. Is this a correct assumption?
function f1(x) {
var y = x.foo;
}
function f2(foo) {
var y = foo;
}
var obj = {foo: "test"};
f1(obj);
f2(obj.foo);

"Memorywise, would it be better to only pass the properties instead of the whole object? Or would this actually create more of a memory issue if my properties are strings? "
That would require more memory. Doesn't really matter if they're strings, since strings are generally implemented as Reference Types as well, but for each argument, there will be a copy of the value instead of just a single copy of the Object reference.
The object reference is very light weight, so you just as just copy that instead of all individual members of the object.
Also, this will be required if you rely on mutations of the object within the function.
In your examples, there's only one property being passed (a string). If your code doesn't rely on mutations of the object itself, then there'll be no significant difference between the two.
In the example that passes the object, the only copy is the object reference. It isn't a pointer, but it is very light weight, and nothing to be concerned about.
In the example that passes the string, it would seem as though it makes a copy of the entire string, but since stings are immutable in JavaScript, implementations generally implement them as reference types as well.
Therefore it's as efficient to pass a single character string as it is to pass a 10,000 character string.

Related

In what way are datatypes immutable? [duplicate]

If a string is immutable, does that mean that....
(let's assume JavaScript)
var str = 'foo';
alert(str.substr(1)); // oo
alert(str); // foo
Does it mean, when calling methods on a string, it will return the modified string, but it won't change the initial string?
If the string was mutable, does that mean the 2nd alert() would return oo as well?
It means that once you instantiate the object, you can't change its properties. In your first alert you aren't changing foo. You're creating a new string. This is why in your second alert it will show "foo" instead of oo.
Does it mean, when calling methods on
a string, it will return the modified
string, but it won't change the
initial string?
Yes. Nothing can change the string once it is created. Now this doesn't mean that you can't assign a new string object to the str variable. You just can't change the current object that str references.
If the string was mutable, does that
mean the 2nd alert() would return oo
as well?
Technically, no, because the substring method returns a new string. Making an object mutable, wouldn't change the method. Making it mutable means that technically, you could make it so that substring would change the original string instead of creating a new one.
On a lower level, immutability means that the memory the string is stored in will not be modified. Once you create a string "foo", some memory is allocated to store the value "foo". This memory will not be altered. If you modify the string with, say, substr(1), a new string is created and a different part of memory is allocated which will store "oo". Now you have two strings in memory, "foo" and "oo". Even if you're not going to use "foo" anymore, it'll stick around until it's garbage collected.
One reason why string operations are comparatively expensive.
Immutable means that which cannot be changed or modified.
So when you assign a value to a string, this value is created from scratch as opposed to being replaced. So everytime a new value is assigned to the same string, a copy is created. So in reality, you are never changing the original value.
I'm not certain about JavaScript, but in Java, strings take an additional step to immutability, with the "String Constant Pool". Strings can be constructed with string literals ("foo") or with a String class constructor. Strings constructed with string literals are a part of the String Constant Pool, and the same string literal will always be the same memory address from the pool.
Example:
String lit1 = "foo";
String lit2 = "foo";
String cons = new String("foo");
System.out.println(lit1 == lit2); // true
System.out.println(lit1 == cons); // false
System.out.println(lit1.equals(cons)); // true
In the above, both lit1 and lit2 are constructed using the same string literal, so they're pointing at the same memory address; lit1 == lit2 results in true, because they are exactly the same object.
However, cons is constructed using the class constructor. Although the parameter is the same string constant, the constructor allocates new memory for cons, meaning cons is not the same object as lit1 and lit2, despite containing the same data.
Of course, since the three strings all contain the same character data, using the equals method will return true.
(Both types of string construction are immutable, of course)
The text-book definition of mutability is liable or subject to change or alteration.
In programming, we use the word to mean objects whose state is allowed to change over time. An immutable value is the exact opposite – after it has been created, it can never change.
If this seems strange, allow me to remind you that many of the values we use all the time are in fact immutable.
var statement = "I am an immutable value";
var otherStr = statement.slice(8, 17);
I think no one will be surprised to learn that the second line in no way changes the string in statement.
In fact, no string methods change the string they operate on, they all return new strings. The reason is that strings are immutable – they cannot change, we can only ever make new strings.
Strings are not the only immutable values built into JavaScript. Numbers are immutable too. Can you even imagine an environment where evaluating the expression 2 + 3 changes the meaning of the number 2? It sounds absurd, yet we do this with our objects and arrays all the time.
Immutable means the value can not be changed. Once created a string object can not be modified as its immutable. If you request a substring of a string a new String with the requested part is created.
Using StringBuffer while manipulating Strings instead makes the operation more efficient as StringBuffer stores the string in a character array with variables to hold the capacity of the character array and the length of the array(String in a char array form)
From strings to stacks... a simple to understand example taken from Eric Lippert's blog:
Path Finding Using A* in C# 3.0, Part Two...
A mutable stack like System.Collections.Generic.Stack
is clearly not suitable. We want to be
able to take an existing path and
create new paths from it for all of
the neighbours of its last element,
but pushing a new node onto the
standard stack modifies the stack.
We’d have to make copies of the stack
before pushing it, which is silly
because then we’d be duplicating all
of its contents unnecessarily.
Immutable stacks do not have this problem. Pushing onto an immutable
stack merely creates a brand-new stack
which links to the old one as its
tail. Since the stack is immutable,
there is no danger of some other code
coming along and messing with the tail
contents. You can keep on using the
old stack to your heart’s content.
To go deep on understaning immutability, read Eric's posts starting with this one:
Immutability in C# Part One: Kinds of Immutability
One way to get a grasp of this concept is to look at how javascript treats all objects, which is by reference. Meaning that all objects are mutable after being instantiated, this means that you can add an object with new methods and properties. This matters because if you want an object to be immutable the object can not change after being instantiated.
Try This :
let string = "name";
string[0] = "N";
console.log(string); // name not Name
string = "Name";
console.log(string); // Name
So what that means is that string is immutable but not constant, in simple words re-assignment can take place but can not mutate some part.
The text-book definition of mutability is liable or subject to change or alteration. In programming, we use the word to mean objects whose state is allowed to change over time. An immutable value is the exact opposite – after it has been created, it can never change.
If this seems strange, allow me to remind you that many of the values we use all the time are in fact immutable.
var statement = "I am an immutable value"; var otherStr = statement.slice(8, 17);
I think no one will be surprised to learn that the second line in no way changes the string in statement. In fact, no string methods change the string they operate on, they all return new strings. The reason is that strings are immutable – they cannot change, we can only ever make new strings.
Strings are not the only immutable values built into JavaScript. Numbers are immutable too. Can you even imagine an environment where evaluating the expression 2 + 3 changes the meaning of the number 2? It sounds absurd, yet we do this with our objects and arrays all the time.

Are all variables in js converted to objects before being executed?

From what I have understood, primitive data types such as a string can also have properties ie string can have .includes . Does that mean all primitive data types are converted to objects before being executed. If yes, what is the point of having distinct difference between primitive data types and objects.
Whenever you try to refer to a property of a string s, JavaScript converts the string value to an object as if by calling new String(s). This object inherits string methods and is used to resolve the property reference. Once the property has been resolved, the newly created object is discarded.
Numbers and booleans have methods for the same reason that strings do: a temporary object is created using the Number() or Boolean() constructor, and the method is resolved using that temporary object.
source Javascript: The Definitive Guide. David Flanagan
When you call a property on a string (lower case) primitive, the JS runtime creates a new instance of a String (upper case) object and copies the string primitive value into the new "wrapper" object, then the property or method that you originally called gets called on the wrapper object and then that wrapper object is garbage collected when the statement is completed. This makes it only seem like some primitives have properties when they actually don't.
If yes, what is the point of having distinct difference between
primitive data types and objects.
The point is that primitives are lightweight entities that have a low memory footprint, whereas Objects can do more and therefore require a larger memory footprint. Also, you can't inherit from a primitive, whereas you can from an Object.
If you'll only be doing limited Object operations, using a primitive is the best approach, but if you know that you'll be using many properties of an Object, it's more efficient to create the Object using a constructor from the start to avoid the constant creation and destruction of wrapper objects.

If all JavaScript types are objects, then why are numbers be passed by value?

In articles about closures, you will often see closures being created inside of loops using self-invoking functions to pass the iterator variable to a returned function expression in order to create a closure around the value of the iterator variable at the time the self-invoking function was invoked, rather than its value after the loop finishes. Here is an example:
var func = [];
for (var i = 0; i < 3; i++)
{
func.push((function(j){ return function(){ console.log(j); }; })(i));
}
// Logs
// 0
// 1
// 2
// to the console
for (var i = 0; i < func.length; i++)
{
func[i]();
}
This technique works with both numbers and strings, based on my simple experiments. However, the same technique does not work with plain JavaScript objects. If an object is passed to a self-invoking function and referenced in a function expression, changes to the enclosed object are visible in the function expression because the value passed to the self-invoking function was a reference to an object and not a copy of the object, as is the case with numbers and strings.
I can understand why this technique would not work with a variable that stores an object, but I don't understand why this technique should work with numbers and strings, whose prototype chains terminate with Object.
Does this mean that strings and numbers are just special cases of objects that are handled differently by the interpreter, or am I suffering from a fundamental misconception?
First, it is not true that "all JavaScript types are objects". Primitive strings, numbers, and boolean values are not objects.
Second, everything in JavaScript is pass-by-value. It's important to understand what "pass-by-value" means. It means that when a function is called, like this:
var someVariable = something;
someFunction(someVariable); // <--- this is the function call
then what the language does is copy the value of someVariable and pass that copy to the function. What a "pass-by-reference" language would do is pass a reference to that variable to the function. Because a copy of the value of the variable is passed to the function in a pass-by-value world, the function has absolutely no way to modify the value of someVariable. In a "pass-by-reference" language, it does.
To some extent, C++ lets you employ either parameter passing scheme. JavaScript does not.
The fact that in JavaScript variables have object references as values sometimes does not mean the language is pass-by-reference. I know that that seems like a silly pedantic distinction, but it's important to understand that "pass-by-value" and "pass-by-reference" are precise terms used to describe language semantics. If they don't have precise meanings, they're useless for that purpose.
One more thing: JavaScript implicitly wraps string, number, and boolean primitive values in wrappers of the corresponding String, Number, and Boolean types when the primitive values are used as if they're objects. That's what happens when you do something as common as:
var five = "hello".length
The left-side operand of the . operator has to be an object, so there's no special-case here: there's an implicit promotion of the primitive string value to a String instance. (What the runtime really does under the covers, well, we can't tell and we shouldn't care. Conceptually, a temporary wrapper object is created, used, and thrown away.)
In javascript there are 6 primitive types: string,number,boolean,null,undefined,symbol - new in ECMAScript 2015. However there are Object wrapper classes for these primitives. All 6 except null and undefined have wrapper classes. Reference These primitive types are passed by value not by reference per the javascript design.

In Javascript, how to differntiate objects which are saved with actual data and objects saved as reference?

Consider I have a object mainObj and I duplicating this object and saving in two other variables ObjD and ObjR.
mainObj = {x:1};
ObjR = mainObj;
ObjD = {};
mainAbjArray = Object.keys(mainObj);
for(i=0;i<mainAbjArray.length;i++){
ObjD[mainAbjArray[i]] = mainObj[mainAbjArray[i]];
}
After above execution, I have two objects when accessed gives sane data but the way of storage is different. So, how to find out if a object is saved as a reference (like ObjR) and saved with actual data (like ObjD)?
ObjR is not precisely an object, it is a name whose value is an object. That value happens to be identical to the value of the name mainObj. The value in question is {x: 1}. Anywhere in your program, writing mainObj or ObjR is semantically identical to writing {x: 1}. The former are names; the latter is a literal object. There is no way to distinguish between the two; in fact, the question is somewhat meaningless.
It is not the case that some objects are "saved with actual data" and others are "saved as reference". An object itself is just an object, the actual data comprising the object. A name is not an object, but rather can be thought of as a kind of pointer to an actual object. Names never point to other names; they point to values.
ObjR = mainObj; does not mean "set ObjR to refer to mainObj". It means "set the value of ObjR to the current value of mainObj". ObjR has no connection whatsoever with the variable mainObj.
Confusion can arise because in normal conversation we do say things like "the object ObjR". You need to keep in mind that this a sort of shorthand for saying "the object to which the variable named ObjR refers."
Consider a simpler example with numbers:
a = 1;
b = a;
Now, can I distinguish between a and b? No. Why would I want to?
You can't. Objects are always saved as a reference.
You can copy them about. mainObj and ObjR contain identical values. There is no way to distinguish them.
ObjD is just another reference to another object which you've made identical by copying all the values across.
You can distinguish between the two objects with == because they are different objects, but you can't tell how the object was created or the variable was populated.

Every Object is a function and every function is Object - Which is Correct?

I was reading this link JavaScript_syntax
This seems to be cyclic - that every function is an Object and every Object itself is a function. Which is the atomic one? Can someone explain in a better way?
Anything that is not a primitive type (undefined, null, number, string, boolean) is an object (or an instance) in JavaScript. That means function inherits from object.
Object instances can contain more instances which can be functions. That's what we call a "method" (since it has an automatic this variable).
Since you can't "call" every Object instance, not every object is a function.
I think this concept is often misunderstood.
A utility to visualize JS types relationship http://jstype.herokuapp.com/#/home
Javascript Data Types
Primitive types - numbers, strings, booleans, null and undefined.
All non-primitive types are object:
var foo = { };
var foo = [1, 2, 3];
var foo = function abc() { return "hello world"; };
var foo = new Number(30);
var foo = new String("Hello World");
var foo = new Boolean(true);
var foo = new RegExp(/[foo]+/);
// All 'foo` are object.
All primitive types have a corresponding Constructor Function wiz. Array, Number, String, Boolean, RegExp. As all functions are objects, they are objects too. So we can call them Constructor Function Objects.
Most of the non-primitive type has prototype property where all inherited stuff lives. Math doesn't have prototype.
All objects inherit from Object.prototype which inherits from null.
object <- Object.prototype <- null
All native functions inherit from Function.prototype which inherits from Object.prototype.
function <- Function.prototype <- Object.prototype <- null
Arrays inherit from Array.prototype which inherits from Object.prototype.
array <- Array.prototype <- Object.prototype <- null
Must read MDN: Inheritance and prototype chain
To get confused Stackoverflow: prototype in JavaScript
Stack Overflow: Function prototype explained
Every function is an object. Objects can contain functions (methods) but an object is not necessary a function.
Also Function is always a property of an object.
This mean that all functions in JavaScript is always bound to an object. If you don't specify an object to bind a function to it's bound to the window object (Also called global functions)
..fredrik
It would be better to say that in JavaScript everything can be treated as an object, that includes primitive types as well as functions types; what the JavaScript interpreter does is that it automatically promotes your primitives and functions to their object wrapper types when you interact with them.
There is also a Function object, an a number of equivalent Wrappers for the other primitives in JavaScript, that means that you can even call methods on functions instances, like:
myFunction(someArg).call(this)
That being said, not every object is in fact a function.
As others have said, functions are objects that can be passed around by reference like other javascript objects. Not all objects are functions, only those that are declared as such.
You will often see methods declared like so:
var myFunc = function(foo, bar) {
...
};
This is to reinforce the fact that the method is a function object and as such it is a property of the object where it is defined, just like any other variable you might define with var.
This is the foundation of the most important feature in javascript, closure.
Every function is an Object.
I'm not an javascript expert, but I cannot see how every Object is a function. (I can see how every object could be a function, but that's different)
Quoting from Working with Objects - MDN Docs
section Using Object Initializers last paragraph:
"In JavaScript 1.1 and earlier, you cannot use object initializers. You can create objects only using their constructor functions or using a function supplied by some other object for that purpose. See Using a Constructor Function."
meant that all objects WERE functions! Specifically, upon evaluation, instances or instantiations of functions.
Literally, ALL objects of that vintage were created syntactically with constructs like:
"newobj = new constructFunctor(arg1,arg2){this.prop1=arg1 /* etc */}(val1,val2)"
AND in the string that makes the object "newobj" there is the word "constructFunctor", the name of a function. The statement is intentionally quoted to impress the fact that it must be eval()'d to be executed. Prior to execution "newobj" is "equated to" a function because the statement MUST have one and "is" one by virtue of "constructFunctor"'s literal existence to define newobj's value upon execution. The quoting, and not, is very intentional in order to elucidate this abstraction. However, because JavaScript DOES have an eval function, this abstraction is in fact intentionally incorporated into the JavaScript language.
The legacy of this is still fundamental to JavaScript, though some syntactic short cuts have been added as "object initializers" using the shorthand notation like: "no={}". That the paragraph quoted above is still resident in the current documentation IS significant for the very reasons noted.
Furthermore, JavaScript also exemplifies the fundamental paradigms of Functional Programming. This defines everything as a function using the abstractions of Recursive Function Theory and the Lambda Calculus! For instance 0(), 1(), 2(), ... are the constant nonary functions better known as 0,1,2,3, ...
JavaScript is completely consistent with a Functional Programming Style approach rather than the common OOPS (pun intended Object Oriented Programming Style).
Just for supplementary to Aaron Digulla's answer.
In javascript not every object is a function. But Object,Array,String and many other built-in objects are functions that used with new operator to create object. I think this is what confused most people.
javascript everything is a hashtable. Ryan Dahl said this in one of his talks. thats what json is also; a hashtable definition. thats why u can access an object using array notation or object property notation. the value of the hashtable can be a function as well which is a hashtable. or rather an associative array
type Object in the console u get { [native code] } which is a hashtable
Object is an abstract data given to a class and that class is assigned to an object. Object can have properties and properties can hold values and functions.
Or simply for the sake of making it easy to understand you can say that anything that is not primitive data type (number,string, boolean, unll & undefined) can be classified as an object.
the selected answer by Aaron Digulla's is not 100% correct because it says,
Anything that is not a primitive type (undefined, null, number,
string, boolean) is an object.
but a string is an object. That is why you can do things like:
myString="Hello World";
x = myString.length;
newString = myString.toUpperCase();
link = myString.link("http://www.hello-world.com/");
And many other methods can be applied to the string object.
You could also initialize the string like:
myString = new String("Hello, World!");
But because a string is also a datatype it is much easier to initialize it by just applying a value.
Not necessarily an answer to the question ... just a clarification/correction of Aaron Digulla's answer.
The selected answer is wrong. In JavaScript everything is a function, except primitive types. Object itself is a function which is called function Object(). Use for example the following code:
<script>
alert(Object);
</script>

Categories

Resources