function user(){
user.name ="Amine";
user.lastName ='Meziane';
document.write(user.name);
};
user();
When executing it writes "user" only and not the name "Amine"
user refers to the user function, which comes with an existing, unassignable name property initialized to the function name. The user.name ="Amine"; assignment is ignored.
As user2357112 pointed out, your Code tries to modify the name property of the function user. This property isn't modifieable. And so it doesn't change. The name property of the function user, contains the name of the function user, which is "user" :-). And this name is what your code prints out.
You can write:
function user(){
var user = {};
user.name = "Amine";
user.lastName = "Meziane";
document.write(user.name);
};
user();
Here user(.name) will not refer to the function user, but to the local variable (var) user, which is initialized with an object literal ({}).
Maybe you wanted to write an constructor function. Then you would add properties to this.
function User(name, lastname){
this.name = name;
this.lastName = lastname;
return this; //optional
};
var userAmine = new User("Amine", "Meziane"); // don't forget "new"
document.write(userAmine.name);
Maybe you can read JavaScript Patterns by Stoyan Stefanov for deeper understanding of JavaScript.
Because the name of the function is read-only. Refer to documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
window.onload = function() {
function user(){
var json = '{"name":"Amine","lastName":"Meziane"}',
obj = JSON.parse(json);
document.body.innerHTML=obj.name+' '+obj.lastName;
}
user();
};
//or
function user(){
var user = {};
user.name ="Amine";
user.lastName ='Meziane';
document.write(user.name);
};
user();
Related
So I created the greeting method, but I am having trouble trying to return the string with the this method. All help would be greatly appreciated please.
function exerciseTwo(userObj){
// Exercise Two: You will be given an object called 'userObj'
// userObject will already have a key on it called 'name'
// Add a method to userObj, called 'greeting'.
// Using the keyword 'this', the greeting method should return the following string:
// 'Hi, my name is ' and the users name.
// eg: If userObj has a name: 'Dan', greeting should return: Hi, my name is Dan'
// NOTE: DO NOT create a new object.
// NOTE: DO NOT create a key called name the key is already on the object.
userObj.greeting = 'Hi, my name is ' + this.name;
return userObj;
}
If you run the function without creating any new objects and call the function, this will have the scope of where you call the function from, which will be window, so you can either create a var name with the value 'users name' or set a property on window directly with window.name = 'users name';
this in JavaScript is a bit loopy.
var name = 'Dan';
console.log(window.name);
function exerciseTwo(userObj){
userObj.greeting = 'Hi, my name is ' + this.name;
return userObj;
}
console.log(exerciseTwo({}));
In the browser DOM you have a window object that is the namespace for everything the page does, so calling exerciseTwo when you are not in an object, this will resolve to window. All variables you create without a namespace will be attached to the window object.
var userObj = { // An object with the name property as Dan
name: 'Dan'
}
userObj.greeting = function () { // Adding a function to the object called greeting
return 'Hi, my name is ' + this.name;
}
console.log(userObj.greeting());
In this instance, when the function is called this has the scope of the object userObj.
I'm trying to make a object private, but not sure how to do that. As you can see the name variable is private, I can't edit it but when it comes to the object that I return, I can edit. I dont want that to be possible, though.
I quite new to object-oriented and private methods in javascript, so could someone tell me what's right and wrong here. :) How can I solve this?
Thanks!
var User = function() {
var name = 'bob';
this.getName = function() {
return name;
}
var otherInfo = {
age: 20,
human: true,
}
this.getOther = function() {
return otherInfo;
}
}
var person = new User();
var name = person.getName();
name = 'jenny';
console.log(person.getName()); // bob
var other = person.getOther();
other.age = 'wtf?';
console.log(person.getOther()); // { age: 'wtf?', human: true }
Primitive values such as Strings are passed by value. This means when you assign a String to your variable, you are setting the actual value of the String to the variable.
Objects are passed by reference. This means when you assign an Object to your variable, you are simply making a reference to the Object, not it's actual value. If you had one Object and assigned it to 6 different variables, each variable would have a reference to the same underlying Object.
In your example, your getOther method is returning a reference to the otherInfo object. So when you set the age property to "wtf", you are setting it on the Object that your variable refers to.
You also declare var name twice.
When you var person = new User(); a var name is declared within the scope of the User function.
When you var name = person.getName(); you are declaring a variable with the same name outside the scope of the User function.
So, when you name = 'Jenny'; the interpreter associates this string the name variable outside the scope of User.
In general, it is a bad idea to use such variables with common names (name, title, id, ...) as global variables. I would refer to the object attributes with this. and define setters as well as getters. You can also ignore the setters and refer to the User attributes with person., like this:
function User() {
this.name = 'bob';
this.getName = function() {
return this.name;
}
this.otherInfo = {
age: 20,
human: true,
}
this.getOther = function() {
return this.otherInfo;
}
}
var person = new User();
console.log(person.getName()); // bob
person.name = 'jenny';
console.log(person.getName()); // jenny
console.log(person.getOther(); // { age: 20, human: true }
person.otherInfo.age = 'wtf?';
console.log(person.getOther()); // { age: 'wtf?', human: true }
You don't have “private” things in object scope in Javascript. The only way to hide things from the outside is with a function scope, like you did with name (a local variable in the function User).
To return an object with the same content every time, you could make the object inside the function. Like this, for instance:
this.getOther = function() {
var otherInfo = {
age: 20,
human: true,
}
return otherInfo;
}
Or just:
this.getOther = function() {
return {
age: 20,
human: true,
};
}
In both cases, you will be creating a new object with every call.
It is happen, because in JS object passes by link - there are not coped from source object.
Just try copy object:
var User = function() {
var name = 'bob';
this.getName = function() {
return name;
}
var otherInfo = {
age: 20,
human: true,
}
this.getOther = function() {
return Object.assign({}, otherInfo);
}
}
var person = new User();
var name = person.getName();
name = 'jenny';
console.log(person.getName()); // bob
var other = person.getOther();
other.age = 'wtf?';
console.log(person.getOther()); // { age: 20, human: true }
Look at the code bellow. I would except that the output would be 123-admin 0-null. But instead its 123-admin 0-admin. Can you explain me why the new keyword does not replace the entire user object?
function User()
{
}
User.prototype.id=0;
User.prototype.role={name:null}
var user = new User();
user.role.name = 'admin';
user.id = 123;
window.document.write(" "+user.id+"-"+user.role.name);
user = new User();
window.document.write(" "+user.id+"-"+user.role.name);
Also in JSFiddle:
https://jsfiddle.net/tfgx77au/6/
The role property is on the prototype, so that object is shared among all instances created with the constructor.
If you wanted a separate role object on each user, you'd have to initialize that in the constructor (or somewhere at least):
function User() {
this.role = { name: null };
}
I am having some trouble understanding function scope in JavaScript:
function Person() {
var _firstName;
var _lastName;
}
personOne = new Person();
personOne._firstName = "Fred";
alert(personOne._firstName);
This outputs "Fred", but I thought the variables of the Person function would only be accessible inside the function. Why does it work?
In JavaScript, objects are dynamically-expandable.
For example:
var obj = {};
obj.firstName = "Matías"; // <-- This adds the property even if it doesn't exist
In the other hand, if you want to declare properties that should be part of the object in the constructor function you need to qualify them with this:
function Person() {
this._firstName = null;
this._lastName = null;
}
Extra info
If you want to avoid objects from being dynamically-expandable, you can use the ECMA-Script 5 Object.preventExtensions function:
var obj = {};
Object.preventExtensions(obj);
// This property won't be added!
obj.text = "hello world";
Because in the line:
personOne._firstName = "Fred";
You assigned a new property to the object with a value of "Fred". It has nothing to do with the (internally-scoped) variable you declared inside the function.
And in the following line, you're actually alerting the value of the newly-created property and not the variable.
See MDN
It works because you create the property _firstName for the object Person.
personOne._firstName = "Fred"; // here you create the property
In the example below I highlighted the fact that _firstName is innacesible.
function Person() {
var _firstName= "Fred";;
var _lastName;
}
personOne = new Person();
alert(personOne._firstName); // output: "undefined"
If you want to make them accesible you can make use of this to add a new property to the object.
function Person() {
var self = this;
self._firstName= "Fred";
var _lastName;
return self;
}
var personOne = new Person();
alert(personOne._firstName); // output: "Fred"
In this line:
personOne._firstName = "Fred";
you are actually creating the property _firstName of the object. it is not the same as the var you created in the constructor function. You can always add new properties to a JavaScript object. Each property of an object is accessible. There is no such thing as a private property.
Due to function scope you will not be able to change the variables inside Person() from outside if you do not make methods available in Person to set the values of those variables.
function Person(firstName, lastName) {
var _firstName = firstName, _lastName = lastname;
this.getFullName = function () {
return _firstName + " " + _lastName;
};
}
var someone = new Person("Some", "one");
someone._firstName = "something else"; // creates new property in the object someone
var fullName = someone.getFullName(); // still returns "some one"
You cannot reference _firstName inside the object declaration. If you want to access the object property you need to declare with this, otherwise the _firstName or _lastName are considered local variables.
So to access the _firstName or _lastName as object properties, you have to declare as in the following way:
function Person() {
this._firstName = "John";
this._lastName = "Doe";
}
You may access _firstName and _lastName after you instantiate the Person.
personOne = new Person();
personOne._firstName = "Fred";
This way you will override the properties already defined in the object constructor. In your case because _firstName is declared inside the Object definition the scope of that variable is bind locally to that object. But when you instantiate the object you assign a new property which extends the originally declared object.
The most widely accepted pattern is to bind the object properties on the object declaration, but declare the object methods on their prototype level.
Like so:
function Person() {
this._firstName;
//...
}
Person.prototype = function() {
getName : function() {
//...
},
setName : function(name) {
this._firstName = name;
}
}
JS objects objects are "expandable", you can add properties dinamically.
function Person() {
var _firstName;
var _lastName;
}
var personOne = new Person();
console.log(personOne); // Person {}
personOne._firstName = "Fred";
personOne._age = 20;
console.log(personOne); // Person {_firstName: "Fred", _age: 20}
You don't actually have access to the _firstName created inside the function scope, but rather you create a property with that name on your newly created object.
In order to expose a property, you attach it using this keyword (which is a reference to the newly created object).
function Person() {
console.log(this); // Person {}
this._firstName = "Sam";
console.log(this); // Person {_firstName: "Sam"}
}
I have the following javascript
function person() {
//private Variable
var fName = null;
var lName = null;
// assign value to private variable
fName = "Dave";
lName = "Smith";
};
person.prototype.fullName = function () {
return this.fName + " " + this.lName;
};
var myPerson = new person();
alert(myPerson.fullName());
I am trying to get an understanding of object orientated techniques in javascript. I have a simple person object and added a function to its prototype.
I was expecting the alert to have "Dave Smith", however I got "underfined underfined". why is that and how do I fix it?
Unfortunately you can't access a private variable. So either you change it to a public property or you add getter/setter methods.
function person() {
//private Variable
var fName = null;
var lName = null;
// assign value to private variable
fName = "Dave";
lName = "Smith";
this.setFName = function(value){ fName = value; };
this.getFName = function(){ return fName; }
};
see javascript - accessing private member variables from prototype-defined functions
But actually this looks like what you are looking for:
Javascript private member on prototype
from that SO post:
As JavaScript is lexically scoped, you can simulate this on a per-object level by using the constructor function as a closure over your 'private members' and defining your methods in the constructor, but this won't work for methods defined in the constructor's prototype property.
in your case:
var Person = (function() {
var store = {}, guid = 0;
function Person () {
this.__guid = ++guid;
store[guid] = {
fName: "Dave",
lName: "Smith"
};
}
Person.prototype.fullName = function() {
var privates = store[this.__guid];
return privates.fName + " " + privates.lName;
};
Person.prototype.destroy = function() {
delete store[this.__guid];
};
return Person;
})();
var myPerson = new Person();
alert(myPerson.fullName());
// in the end, destroy the instance to avoid a memory leak
myPerson.destroy();
Check out the live demo at http://jsfiddle.net/roberkules/xurHU/
When you call person as a constructor, a new object is created as if by new Object() and assigned to its this keyword. It is that object that will be returned by default from the constructor.
So if you want your instance to have properties, you need to add them to that object:
function Person() {
// assign to public properties
this.fName = "Dave";
this.lName = "Smith";
};
Incidentally, by convention functions that are intended to be called as constructors are given a name starting with a capital letter.
You're declaring those variables as local to the function, instead of making them part of the object. In order to put them in the instance, you've got to use 'this' in the constructor as well. For example:
function person() {
this.fName = 'Dave';
this.lName = 'Smith';
}
person.prototype.fullName = function () {
return this.fName + " " + this.lName;
};
var myPerson = new person();
alert(myPerson.fullName());
In the constructor you should assign your variables to this:
this.fName = null;
this.lName = null;
But then they are not private. JavaScript does not have private variables like a "classic" Object Oriented language. The only "private" variables are local variables. An alternative to the above is to assign getter/setter methods to this within the constructor.