Please clarify for me what the term binding means in JavaScript. I've started to read the book 'Eloquent JS' and there are lots of occurrences of this word. Does it just mean variable? Here are few examples from the book:
So if you know that the property you are interested in is called color, you say value.color. If you want to extract the property named by the value held in the binding i, you say value[i].Property names are strings. They can be any string, but the dot notation works only with names that look like valid binding names.
Bindings can also be changeable or constant, but this is separate from the way their values behave. Even though number values don’t change, you can use a let binding to keep track of a changing number by changing the value the binding points at. Similarly, though a const binding to an object can itself not be changed and will continue to point at the same object, the contents of that object might change.
I've found out what it is (in this book in an earlier chapter). Here is the snippet:
How does a program keep an internal state? How does it remember things? We have seen how to produce new values from old values, but this does not change the old values, and the new value has to be immediately used or it will dissipate again. To catch and hold values, JavaScript provides a thing called a binding, or variable:
let caught = 5 * 5;
That’s a second kind of statement. The special word (keyword) let indicates that this sentence is going to define a binding. It is followed by the name of the binding and, if we want to immediately give it a value, by an = operator and an expression.
The previous statement creates a binding called caught and uses it to grab hold of the number that is produced by multiplying 5 by 5.
Binding is a general term to mean that your symbol or variable points to some location in memory. This is also illustrating the principle in JavaScript that even when you declare an object using const, you can still manipulate the properties of that object. Only the reference to the object itself cannot be redefined.
So you can't say myObj = {greeting: "Hello Stack Overflow"} and then myObj = someOtherObj. But you can say myObj.greeting = "Beep Boop"
Okay, let me clarify. The first question what is a binding:
A binding is a symbol, variable, constant, etc. that points to some literal value, or object in memory.
In reference to your book, it says:
const myObj = { color: blue }; // the property color is defined on this object
myObj["color"]; // => "blue" The color property can be accessed by passing in a string
myObj = anotherObj; // not allowed, you declared it with const
The reference or binding is to the object in memory and that cannot change because you declared this reference with const. But you can modify the properties of the object in memory. The object itself is mutable.
Any further discussion of bindings is a discussion on Lexical Scope.
Related
My understanding of the data type is as follows. If we consider a machine like a mill that can take in rice, barley, corn, kidney beans, chickpeas, black beans, etc. So I understand the mill to be the program that processes data such as rice, barley, etc. The data are rice, barley, beans but they differ in types. Rice is of a different type than barley etc.
In javascript, i noticed objects mentioned under data types.
https://javascript.info/types#objects-and-symbols
It makes sense that 23 is data of type number, "cat" is data of type string, true is data of type "boolean" but object seems to be more like a data container rather than a data type. For instance, typeof([]) says it is an object. Now array seems like a data container rather than data and type of a data container doesn't make sense. To me, it makes sense that a data can have a type but a container where we put data having a type is confusing.
So I appreciate if someone can enlighten me. Array seems to be a container and not data and cannot have a type.
I appreciate any guide. Thanks!
On a general, theoretic level, an object consists of data that describes the object, and behaviours that act on that object. Before Object Oriented Programming, data was data, and code was code; if you needed to load some data, and draw it on the screen, chances are those two pieces of code would be in different places of your code base. OOP brings data and behaviour together for better conceptual organisation. It also allows some objects to share behaviour by sorting them into classes (e.g. "barking" is not something that needs to be coded for every dog individually) or by creating object prototypes (same idea, different approach). Furthermore, it allows different objects to specify different ways of performing the same behaviour (e.g. both cats and wolves know about hunting, though they go about it differently).
On a mechanical JavaScript-specific level, "object" is a data structure that can store various values under string keys. It is thus superficially similar to arrays, which again store values, but under integer keys.
However, "value" in JavaScript also includes functions, which is how JS object achieves the first objective (being a repository of related data and code that governs its behaviour). The second objective is achieved by prototypal inheritance:
let Mammal = function() {
}
let typicalMammal = new Mammal();
typicalMammal.legs = 4;
Mammal.prototype = typicalMammal;
let Dog = function() {
};
let typicalDog = new Mammal();
typicalDog.sound = function() { console.log("woof") };
Dog.prototype = typicalDog;
let fido = new Dog();
fido.colour = "yellow";
console.log("Fido:", fido);
fido.sound();
The third is also achieved: if we had a cat, we could just tell happy.sound() and it would do a "meow". We don't need to know if something is a dog or a cat, just that they know how to make a sound, and dynamic dispatch will do the rest.
It is also of note that when you invoke a function in an object with a dot notation like this, the function is interpreted as "method" - a function that knows which object it is acting on, by setting a special variable this. In this case, within the method sound, this would have the same value as fido.
Specifically with arrays, they are a kind of object that knows how to contain multiple values indicated by an integer index, how to be indexed, how to tell its length, how to iterate on its elements etc.
However, note that "variable" is something different entirely. One could conceptualise that variable is a data structure with a name and a value; but you can't typically access variable's name. A variable is not a value itself; you can't put a variable into a data structure, just copy its value there. It is more of a language artifact than a data type.
ECMAScript standard defines eight data types, 7 primitive types and Object.
In JavaScript, objects are a collection of properties and property values can be values of any type, for example an object with an attribute of type "number".
let obj = { num: 3 }
and you can test
typeof obj.num
will return "number", but
typeof obj
will return "object" I suppose because inheritance of prototype Object
All objects in JavaScript are descended from Object, all objects inherit methods and properties from Object.prototype.
In your example of an array. In javascript the array variable has a prototype of Array but that's an object that has a prototype of Object.
typeof([])
I think that's why is returning you "object".
Here are some links about data structures:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
JavaScript has only one data type for containers and it's called "object".
Arrays are containers and so their data type is "object". Like arrays there are other kinds of specialist object classes such as "function" (they contain code and are callable), sets and weak sets for example.
Significantly the JavaScript typeofoperator does not always return the data type of its operand. This is due to early implementation details of the operator which can not now be changed - and programs have long since adjusted to the actual implementation:
typeof null returns "object". The data type of null is "null".
typeof function returns "function". The data type of a function is "object".
...variable is a container and is not data
Variables are not so much a container as an identifier of where a value is stored. Variables in JavaScript are weakly typed which means the data type of a value is not determined by the variable (or object property) to which a value has been assigned but by the internal memory construct used to hold the value. That is to say, type is obtained from the value stored, not the variable used to access it.
Object values
An object value stored in a JavaScript variable is some kind of memory pointer to a data structure whose location and implementation details are private and only known to the JavaScript engine.
It makes sense to call objects values a data type in JavaScript for the same reason pointers in C have a data type depending on what they point to. It also explains why if you assign the same "object value" to two variables, they will both then point to the same object data set held at some unknown location in memory.
The major difference with JavaScript object values is that you can't perform pointer arithmetic on them and must rely on object property notations object.propertyName or object["propertyName"] to directly access properties of an object.
Array objects
JavaScript arrays are objects which use positive integer values, converted to a string, to access array entries being held as string properties of the array object.
Unlike a typed array, index values to access entries of an Array object do not have an upper bound nor do they need to be consecutive - memory is not allocated to store entries which have not been set.
TLDR;
JavaScript arrays are implemented as associative lookup tables. Their data type is "object" and they inherit properties and methods from Array.prototype and Object.prototype.
They are called "exotic" objects in ECMAScript standards because they monitor access to see if the property name used represents a non-negative integer and maintain the array object's length property if it is.
Early JavaScript documentation went out its way not to mention pointers, presumably to avoid confusing BASIC programmers. Documentation used "object" to mean a data structure, object values were stored as pointers, and the short hand property access operator chosen was . instead of the -> operator for pointer access used in the C language family.
I have what seems like it should be a simple operation. For each bridgedSection, I check for a potentialSection with an id that matches the bridged.referenceSection
Then I take that result, parse the HTML on the object with Cherio, make a slight modification (using an id for testing), and then store both the bridgedSection and the modified result on an object, then push that object to the array.
If I log the new object BEFORE pushing, I get the correct object values. If I log it from the array I get incorrect values only for reference.section. bridgedSection is fine, but reference.section matches across all entries in the array.
To say that I'm thoroughly flummoxed is an understatement. Can anyone shed some light on what I am (clearly) doing wrong?
var sectionCount = 0;
bridgedSections.forEach(bridged => {
var obj = potentialSections.find(obj => obj._id == bridged.referenceSection);
$ = cheerio.load(obj.html);
$(".meditor").html(bridged._id);// dropping the id here so it's easy to see if it was updated
obj.html = $.html();
obj.rand = Math.floor(Math.random() * 1000); // can't seem to add to obj either
var thisSection = {
referenceSection: obj,
bridgedSection: bridged,
}
console.log(thisSection) // correct value logged
currentSections.push(thisSection);
sectionCount++;
});
console.log(currentSections);
// this logs an array of the correct length but each
// {}.referenceSection is identical to the last entry pushed above
To try to clarify what both of the above folks are saying, the JavaScript language (like many others) has the concept of references, and makes very heavy use of that concept.
When one variable "refers to" another, there is only one copy of the value in question: everything else is a reference to that one value. Changes made to any of those references will therefore change the [one ...] underlying value (and, be reflected instantaneously in all of the references).
The advantage of references is, of course, that they are extremely "lightweight."
If you need to make a so-called "deep copy" of an array or structure or what-have-you, you can do so. If you want to push the value and be sure that it cannot be changed, you need to make sure that what you've pushed is either such a "deep copy," or that there are no references (as there obviously are, now ...) to whatever it contains. Your choice.
N.B. References – especially circular references – also have important implications for memory management (and "leaks"), because a thing will not be "reaped" by the memory manager until all references to it have ceased to exist. (Everything is "reference counted.")
And, all of what I've just said pretty much applies equally to every language that supports this – as most languages now do.
Javascript is passes function parameters by reference. This means the following happens:
derp = {a:1}
function passedByRef(param){
param['a'] = 2;
}
passedByRef(derp)
console.log(derp['a']) // 2
So when you pass a json object to a function, if you modify said object in the function it will change the original object. You probably want to make a deep copy of bridged before you assign it to thisSection because if you modify the version of bridged later on in thisSection it will modify the original object.
Here is a post that talks about cloning objects or you could look into something like immutable js
I think you need to look into Javascript deep copy.
You are modifying the original object when you modify the second assigned variable, because they are pointing to the same object. What you really need is to duplicate the object, not simply making a pointer to it.
Take a look at this:
https://scotch.io/bar-talk/copying-objects-in-javascript#toc-deep-copying-objects
The concept of functions being objects in JavaScript would be ok with me if I could understand the following question. I have searched around and looked into the javascript engine to try and find the answer, but no explanation I've found so far sits well in my mind...
An object like the one below is understandably layed out in a hash map type of construct.
var person = {
firstName:"John",
lastName:"Doe",
age:50,
eyeColor:"blue"
};
However, to say this is also an object is where I get stuck:
var name = function () {
alert ('name');
}
In terms of memory, how is this function stored?
Are the statements inside the "hash map" of a function layed out in an execute order? So each property is called upon after the other?
I'm probably missing something or visualising something wrong.
Thanks.
P.S
To clear up question 2,
Say I have an if statement inside my function... will that be stored in a property accessible through one of its properties?
Every object in javascript has properties (key-value pairs identified by strings or symbols) and it has internal slots.
The function object name is stored in the same format as the person object, but their internal slots differ.
person's properties are firstName, lastName, age and eyeColor, each holding the respective primitive value
person's internal slots are (amongst others):
[[prototype]], pointing to Object.prototype
name's properties are name, prototype and length (as typical for Function instances)
name's internal slots are (amongst others):
[[prototype]], pointing to Function.prototype
[[ECMAScriptCode]], pointing to the code of the function
[[Environment]], pointing to the scope the closure was created in
Disclaimer: That's only how it behaves, engines may implement this however they want. Still, it serves well as a mental model, and it's important to understand that objects have a layer below the publicly visible properties.
Functions are objects, in that they can have properties and methods. Unlike objects, they can also be called and will always return a result.
Note that the ECMAScript (i.e. JavaScript) language specification describes how Function objects should behave rather than underlying implementation, so the in-memory representation of the object will depend on implementation.
Regarding 2: Note that the full text of a Function might be stored in the functionBody property, however the body of a Function does not have to be JavaScript. It could be native code, for example, that is not meaningful to return in a string.
If you just want to do regular JavaScript coding, I don't think you really need to worry about how the function is stored by the browser or server or whatever. I do think you are misunderstanding the object-nature of a function. The lines of code inside the function are not individual parts of a hash map. Rather (and this only begins to touch on the concept), a function can have properties with names and values just like a regular object can have such properties. The following code demonstrates this.
var myFunc = function() {
var x = "hello".toUpperCase();
document.write('<p>' + x + '</p>');
};
myFunc.favoriteColor = "red";
myFunc(); // runs the function and shows the text "hello"
document.write("<p>" + myFunc.favoriteColor + "</p>"); // shows the text "red"
The answer to 1. is: It depends on the implementation.
The 2nd question doesn't make any sense.
I think you are looking at the syntax, and assuming that because the way data is declared, and the way functions are declared, that a function can be treated as data in the language.
This is not the case.
There are languages where this IS the case. Lisps and Prolog being the most common examples. see:
https://en.wikipedia.org/wiki/Homoiconicity
I tried googling but couldn't find a precise answer, so allow me to try and ask here. If the question does not seem proper, please let me know and I'll delete it.
In JS you've got three different way of writing certain build in functionalities:
str.length
str.toString()
parseInt(str)
I wonder if there is a reason behind these different ways of writing. As a new user I don't grasp why it couldn't be streamlined as: length(str) / toString(str) / parseInt(str) or with dot formulation.
I however think if I do know the reason behind these differences, it would give me a better understanding of JavaScript.
Length is one of the attributes of string in JavaScript. Hence you use string.length to get the length of the string.
toString is a function for string objects, hence we use stringobj.toString().
parsInt(str) is a global function which takes string as a parameter.
JavaScript is object-oriented, so there are functions or procedures which require first an object to use as this in their bodies. str.length is a property, both syntactically and semantically. It doesn't require any parameters and represents some quality of the object. obj.toString() is a method (a function attached to an object), which doesn't represent any characteristics of the object, but rather operates on its state, computes some new values, or changes the state of the object a lot. parseInt(str) is a "global" function, which represents an operation not attached to any type or object.
Under the hood, these three ways may be well implemented with just calling a function, passing this as the first parameter (like C# does, for example). The semantic difference is the important one.
So why not use just the third syntax, like for example PHP does? First, it doesn't bloat the global environment with lots of functions which only work for one specific case and type, allowing you to specify any new function you want without breaking the old functionality. Second, it ecourages you to use object-oriented concepts, because you can already see working objects and methods in the language, and can try to make something similar.
And why isn't parseInt a method? It can as well be str.toInt() without any issues, it's just the way JavaScript designers wanted it to be, although it seems also a bit logical to me to make it a static method Number.parseInt(str), because the behaviour of the function is relevant more to the Number type than the String type.
JavaScript is based around objects. Objects have properties (e.g. a User object may have name and age properties). These are what define the user and are related to the user. Properties are accessed via dot-notation or brackets notation (to access Eliott’s age, we’ll use either eliott.age or eliott['age'] — these are equivalent).
These properties can be of any type — String, Number, Object, you name it — even functions. Now the proper syntax to call a function in JS is to put round brackets: eliott.sayHello(). This snippet actually fetches Eliott’s sayHello property, and calls it right away.
You can see Eliott as a box of properties, some of which can be functions. They only exist within the box and have no meaning out of the box: what would age be? Whose age? Who’s saying hello?
Now some functions are defined at the global level: parseInt or isNaN for instance. These functions actually belong to the global box, named window (because legacy). You can also call them like that: window.parseInt(a, 10) or window.isNaN(a). Omitting window is allowed for brevity.
var eliott = {
name: 'Eliott',
age: 32,
sayHello: function () { console.log('Hello, I’m Eliott'); }
};
eliott.name; // access the `name` property
eliott.age; // access the `age` property
eliott.sayHello; // access the `sayHello` property
eliott.sayHello(); // access the `sayHello` property and calls the function
sayHello(eliott); // Reference error: `window.sayHello` is undefined!
Note: Some types (String, Number, Boolean, etc.) are not real objects but do have properties. That’s how you can fetch the length of a string ("hello".length) and reword stuff ("hello, Eliott".replace("Eliott", "Henry")).
Behaviour of these expressions is defined in ECMAScript grammar. You could read the specification to understand it thoroughly: ECMAScript2015 specification. However, as pointed out by Bergi, it's probably not the best resource for beginners because it doesn't explain anything, it just states how things are. Moreover I think it might be too difficult for you to be able to grasp concepts described in this specification because of the very formal language used.
Therefore I recommend to start with something way simpler, such as a very basic introduction to JavaScript: JavaScript Basics on MDN. MDN is a great resource.
But to answer your question just briefly:
str.length is accessing a property of the str object.
parseInt(str) is a function call
str.toString() is a call of a function which is a property of the str object. Such functions are usually named methods.
Functions and methods are in fact very similar but one of the differences (except for the obvious syntax difference) is that methods by default have context (this) set to refer to the object which they're part of. In this case inside of toString function this equals to str.
Note: Accessing a property (as in str.length) could in effect call a getter function but it depends on how the object is defined, and is in fact transparent for the user.
Within instances of objects I like to use the closure mechanism to simulate private member variables. For a potential large number of created objects I don't need some of the private members though, but I have to declare them for them to be used in the closure, like "one", "two" and "three" here:
var obj=function()
{
var one;
var two;
var three;
var M=function()
{
one=5;
};
};
(Don't mind that this is not actually a working example of my setup, it's just to demonstrate the use of the closure over the three vars with M.)
Do the var statements themselves already consume memory, or does that depend on actually assigning something to these vars like with "one"?
The interpreter has to store information about scope - one = 5 will change the local variable one instead of creating a global variable (which would happen with e.g. four = 5). This information must cost some memory somehow. This memory usage also applies before assigning a value to one, because the information has to be available at the time you're assigning.
How much memory it will cost is difficult to say since it differs per interpreter. I guess it isn't enough to worry about.
Note that two/three are not used at all and may be garbage collected in this example. (Actually, you don't expose M either, so everything may be garbage collected right away in this example.)
When declaring a variable without assigning a value to it, there still needs to be some memory available for it, otherwise you cannot make a reference to the variable later in the program. I don't think it's a noticeable amount of memory being used and won't make a difference.
When declaring a variable, a memory space is reserved for it and allow you to store to or retrieve from that memory with the name you chose for the 3 variables. Such a space is empty until you fill it with a value (two/tree will remain null). This is performed with the assignment operation. The assignment operation gives a value to a variable.