Javascript function, private public value - javascript

In javascript as I know, we can make class-like object using function
but is it possible to set private and public funciton and variable in function?
example.
var a = function(){
this.public = "hello"
var private = "hello"
this.public_func = function(){ console.log("private function");};
var private_func = function(){ console.log("public function");};
}
so public, public_func are public attribute and private,private_func is private attribute
am I right?

The private and public properties or functions come into effect only when you create an object out of your class a.
So try this in console:
var b = new a();
Then inspect b, and you will see only :
a {public: "hello", public_func: function}

The code that works as you described:
var a = function(){
this.public = "hello";
var private = "hello";
this.public_func = function(){
console.log("public function");
//calling the 'private' function.
private_func();
};
var private_func = function(){
console.log("private function");
};
}
But this way doesn't inherits.Check prototype inheritance.
Take care with reserved words:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Reserved_Words

You can mimic the private properties/functions like other class based languages and there are so many ways to do that, for example this is an example of exposing some public members by explicitly returning an object (Fiddle):
var MyClass = (function(){
var privateProp = "Private property accessed via public function";
var privateFunc = function(){
console.log(privateProp);
};
// Expose these as public members
return {
'publicProp':'Public Prop',
'publicFunc':function(){
privateFunc();
}
};
})();
// Use
console.log(MyClass.publicProp); // Public Prop
MyClass.publicFunc(); // Private property accessed via public function
It's a big term and you need to read books and probably articles on this topic (OOP JavaScript), you may read Learning JavaScript Design Patterns book online written by Addy Osmani. It's a good one.

Related

Inheriting from a C++ class in JavaScript

I'm using V8 in a C++ program for extensions. I want to be able to
create objects in JavaScript that "inherit" from a base class in C++.
This is a simple hierarchy in C++:
class animal
{
public:
void move();
virtual void vocalize() = 0;
};
class cat : public animal
{
public:
void vocalize() override;
void ignore_owner();
};
This is cat implemented in JavaScript instead of C++:
function cat()
{
this.vocalize = function() {}
this.ignore_owner = function() {}
}
add_animal(new cat);
where add_animal() is a global function implemented in C++:
void add_animal(v8::Local<v8::Object> o);
In add_animal(), I manually add the move property pointing to a C++
function and make sure that the vocalize property exists and is a
function.
var c = new cat;
c.ignore_owner(); // JavaScript code
c.move(); // error, undefined
add_animal(c);
c.move(); // okay, C++ code
My experience in JavaScript outside of web pages is limited. Is this a
scheme that makes sense? The fact that add_animal() is used to both
add the "base class" properties and add the animal to a list looks
counter-intuitive to me. I could add a second function:
var c = new cat;
make_animal(c);
add_animal(c);
but this requires discipline and looks convoluted.
I could also expose animal, use it to create objects and add the
cat-specific properties afterwards:
function make_cat(c)
{
c.vocalize = function() {}
c.ignore_owner = function() {}
}
var c = new animal;
make_cat(c);
add_animal(c);
but this looks weird to me.
What is the best way to "inherit" from a C++ class?
Just expose your base class to JavaScript (see the official embedder's guide for an example), and then use regular JavaScript inheritance:
function Cat(name) {
this.name = name;
}
var catproto = Cat.prototype = new Animal();
catproto.vocalize = function() { /* cat-specific override */ }
catproto.ignore_owner = function() { return true; /* :-P */ }
catproto.purr = function() { /* you can add new methods too */ }
var c = new Cat("Kitty");
c.move(); // Inherited.
c.vocalize(); // Meow.

Is there a rather complete definition of a JavaScript class [duplicate]

I'm new in javascript.
How can I declare a class in javascript for example with property that named username.
then after username property valued a function is run.
In C# it is something like this :
public int M_A
{
get
{
return m_a;
}
set
{
m_a = value;
RunFunction();
}
}
Javascript doesn't have a class-based inheritance, it uses a prototype-based. Additionally, it doesn't provide support for getters and setters (in most versions).
Here would be one way to write your example:
var ExampleClass = function(){
var _m_a;//private instance
this.m_a = function(){
if(arguments.length){
_m_a = arguments[0];
}else{
return _m_a;
}
};
};
Usage:
var inst = new ExampleClass();
inst.m_a(5);//provide an argument to set it
console.log(inst.m_a());//no arguments to get it
Since we're just approximating a class system, there's actually a couple ways to do this. Here's another:
var ExampleClass = function(){
this._m_a = null;
};
ExampleClass.prototype.get_m_a = function(){
return this._m_a;
};
ExampleClass.prototype.set_m_a = function(value){
this._m_a = value;
};
Usage:
var inst = new ExampleClass();
inst.set_m_a(5);
console.log(inst.get_m_a());
console.log(inst._m_a);//annoying thing is the private property is accessible
For a better understanding of prototypal inheritance and javascript class systems, check out these posts:
Simple JavaScript Inheritance by John Resig (creator of jQuery)
Classical Inheritance in JavaScript by Douglas Crockford
JS Class - a Class framework for javascript
You can do something like this:
var M_A = function()
{
var m_a; //private variable
this.get = function()
{
return m_a;
}
this.set = function(value)
{
m_a = value;
RunFunction(); //run some global or private function
this.runPublic(); // run a public function
}
}
Then you can do:
var ma = new M_A();
ma.set(16);
alert(ma.get()); //alerts `16`
Demo: http://jsfiddle.net/maniator/72bnW/

Can one access a private class property in a public method?

Newbie Javascript question:
how does one access a private class property in a public method? In all the example I see a public prototype function accessing public (this.property). Is it possible to access a private property in a public method?
This pattern is known as a "privileged" method. It looks something like this:
function MyClass() {
var secret = "foo";
this.tellSecret = function() {
return secret;
};
}
var inst = new MyClass();
console.log(inst.tellSecret()); // => "foo"
console.log(inst.secret); // => undefined
This works because the private variable is in a closure. The problem with this is that we are putting the privileged method on each instance, rather than the prototype. This is not ideal. Often, instead of having private variables in JavaScript, authors will just use a leading underscore which is conventionally used to imply that public methods/properties should be treated as private:
function MyClass() {
this._secret = "foo";
}
MyClass.prototype.tellSecret = function() {
return this._secret;
};
Here is a little demo:
var Foo = function(name){
this.name = name;
var t = name;
if(typeof(this.show) != 'function'){
Foo.prototype.show = function(){
console.log(t);
console.log(this.name);
};
}
};
var a = new Foo('a');
var b = new Foo('b');
b.show(); // ...
Hope it can help you out.

Is it possible to call an instance variable inside of a private function in javascript?

I have a function defined in javascript that acts as a class. Within it, I have several public methods defined, but there is one private method, and I need to access one of the public methods within it.
function myClass(){
this.myPublicMethod = function(a,b){
var i = a*b;
return i;
}
function myPrivateMethod(){
var n = this.myPublicMethod(2,3);
}
}
This doesn't work. Is there a way to access myPublicMethod within myPrivateMethod?
You simply have to specify the value of this when calling your private method using Function.prototype.call.
myPrivateMethod.call(this);
E.g.
function myClass(){
this.myPublicMethod = function(a,b){
var i = a*b;
return i;
}
function myPrivateMethod(){
var n = this.myPublicMethod(2,3);
}
//calling private method in the *scope* of *this*.
myPrivateMethod.call(this);
}
Please note that having true private members (that aren't functions) comes at the cost of not taking advantages of prototypes. For that reason, I prefer to rely on naming conventions or documentation to identify private members rather than enforcing true privacy. That holds only for non-singleton objects.
The following example demonstrates what is being said above.
//Constructors starts by an upper-case letter by convention
var MyClass = (function () {
function MyClass(x) {
this._x = x; //private by convention
}
/*We can enforce true privacy for methods since they can be shared
among all instances. However note that you could also use the same _convention
and put it on the prototype. Remember that private members can only be
tested through a public method and that it cannot be overriden.*/
function myPrivateMethod() {
this.myPublicMethod1();
}
MyClass.prototype = {
constructor: MyClass,
myPublicMethod1: function () {
//do something with this._x
},
myPublicMethod2: function () {
/*Call the private method by specifying the *this* value.
If we do not, *this* will be the *global object* when it will execute.*/
myPrivateMethod.call(this);
}
};
return MyClass;
})();
You can try this to defeat the local scoping:
function myClass(){
this.myPublicMethod = function(a,b){
var i = a*b;
return i;
}
// Capture the original context of `this` myClass
var self = this;
function myPrivateMethod(){
var n = self.myPublicMethod(2,3);
}
}
We use self to maintain a reference to the original this even as the context is changing (since we want to call the public method int the private method).
One way to do this is defining every method as private first, and making the ones you want public in the end (myPrivateMethod will reference the original myPublicMethod even if myClass.myPublicMethod is overridden):
function myClass(){
var myPublicMethod = function(a,b){
var i = a*b;
return i;
}
var myPrivateMethod = function (){
var n = myPublicMethod(2,3);
}
this.myPublicMethod = myPublicMethod;
}
You could write
var myPublicMethod = this.myPublicMethod = function()...
So there was a private and a public instance created.
Just seems cleaner to me.
You could potentially pass the public function to the private function as a parameter and then call it.
this.myPublicMethod = function(a,b){
alert(a * b);
}
function myPrivateMethod(publicMethod){
var n = publicMethod(2,3);
}
myPrivateMethod(this.myPublicMethod);
Here is a working fiddle.. http://jsfiddle.net/rxtB2/3/
An alternative to invoking call could be to attach the method directly to the myClass Function object.
function myClass(){
myClass.myPublicMethod = function(a,b){
var i = a*b;
return i;
}
this.myPublicMethod = myClass.myPublicMethod;
function myPrivateMethod(){
var n = myClass.myPublicMethod(2,3);
return n;
}
console.log("Calling myPrivateMethod()");
console.log(myPrivateMethod());
}
If you only want "private" methods then your pattern for defining it is wrong. I think methods that can access "private" methods are called privileged methods but can be wrong.
The pattern for creating them is the following (added instance variables and inheritance in the example):
// added to show inheritance
var Parent = function(){
//instance members
this.parentInstanceVar=["parent"];
};
var Class = function() {
//1st step to "inherrit" from Parent
// take ownership of Parent instance members
Parent.call(this);
//to pass all arguments to Parent constructor:
//Parent.apply(this,arguments);
//to pass specific agruemtns to Parent
//Parent.call(this,arg1,arg5);
this.someIntanceVar=["Class instance"];
};
Class.prototype=(function(parent){
var ret=(parent&&parent.prototype)?
Object.create(parent.prototype):
Object.create({});
//repair the constructor
ret.constructor=Class;
var myPrivateMethod = function() {
return this.someIntanceVar;
};
//privileged method calling "private method"
ret.myPriviligedMethod=function(){
return myPrivateMethod.call(this);
};
return ret;
}(Parent));//2nd step to "inherit" from Parent
//non privileged method
Class.prototype.nonPrivileged=function(){
//can't accesss myPrivateMethod here
};
//some tests creating 2 instances
var c1=new Class();
var c2=new Class();
c1.parentInstanceVar.push("added in c1");
c1.someIntanceVar.push("added in c1");
console.log(c2.parentInstanceVar);//=["parent"]
console.log(c2.someIntanceVar);//=["class instance"]
console.log(c1.myPriviligedMethod());//=["Class instance", "added in c1"]
console.log(c2.myPriviligedMethod());//=["Class instance"]
//reason why we repaired the constructor:
console.log((new c1.constructor()) instanceof Class);//=true
This pattern only handles instance shared private members. If you need instance specific private members you can't use prototype for any privileged methods (methods that need access to "private" instance specific members). You can use use a function that returns an object containing closures but I would really not use this pattern as it ignores prototype and the benefits that come with it, makes testing harder and is a huge pain to clone.
var createClass=function(privateInstanceVal){
var privateMethod=function(val){
privateInstanceVal.push(val);
return privateInstanceVal;
};
return{
publicInstanceVar:[],
publicMethod:function(val){return privateMethod(val);}
}
};
c1=createClass([]);
var b = c1.publicMethod(33);
console.log("b is:",b);
b.push("because I returned the private I made it public");
console.log(c1.publicMethod(0));//=[33, "because ... public", 0]
The sample shows a mistake sometimes made by returning "private" you made it public. Instead you can return a copy: return privateInstanceVal.concat([]);

Private members in javascript

Can anyone please tell me how do we use or declare private members in javascript.I will appreciate an example.I am new to this
Douglas Crockford has a write-up on Private Members:
Private members are made by the constructor. Ordinary vars and parameters of the constructor becomes the private members.
function Container(param) {
this.member = param;
var secret = 3;
var that = this;
}
This constructor makes three private instance variables: param, secret, and that. They are attached to the object, but they are not accessible to the outside, nor are they accessible to the object's own public methods. They are accessible to private methods. Private methods are inner functions of the constructor.
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
}
The private method dec examines the secret instance variable. If it is greater than zero, it decrements secret and returns true. Otherwise it returns false. It can be used to make this object limited to three uses.
By convention, we make a private that variable. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.
Private methods cannot be called by public methods. To make private methods useful, we need to introduce a privileged method.
here is one way to do it:
function TheClass() {
var _this = this;
var privateMember = 'foo';
this.publicMember = 'bar';
var privateMethod = function(){
// things happen here
};
this.publicMethod = function(){
//other things here
_this.publicMember = 'sparky';
return privateMember;
};
}
var myObj = new TheClass();
alert(myObj.privateMember); //won't work
alert(myObj.publicMember); //should work
alert(myObj.publicMethod()); //should work too
see this working fiddle and play a bit with it ;)
JavaScript doesn't have private variables per-say. In JS variables are scoped to the top of the closest function. So creating a function (or closure) is a way to make private variables only accessible within that scope. The important thing to remeber is to always use var to declare variables, otherwise, even inside a function, the variable will become global, and that's bad.
If you're working with prototype inheritance then it's as easy as creating a constructor and any variable declared with var will be private and declared with this will be public.
function Bar() {
var foo = ''; // private
this.baz = function() {}; // public
}
var bar = new Bar(); // create new instance of Bar
alert(bar.foo); // error
alert(bar.baz); // function
Also the above constructor is very simple, typically you'd put function methods on the actual prototype of the object, like Bar.prototype.baz = function(){}.
If you're working with a singleton for example, you can use the module pattern:
var bar = (function(){ // bar is public
var foo = ''; // foo is private
function baz() {}; // baz is private
return {
baz: baz // expose 'baz' as a public member of 'bar'
}
}());
alert(bar.foo); // error
alert(bar.baz); // function
You can try this https://www.npmjs.com/package/private-members
This package will save the members by instance.
const pvt = require('private-members');
const _ = pvt();
let Exemplo = (function () {
function Exemplo() {
_(this).msg = "Minha Mensagem";
}
_().mensagem = function() {
return _(this).msg;
}
Exemplo.prototype.showMsg = function () {
let msg = _(this).mensagem();
console.log(msg);
};
return Exemplo;
})();
module.exports = Exemplo;
Private members are made by the constructor. Ordinary vars and parameters of the constructor becomes the private members.
function Container(param) {
this.member = param;
var secret = 3;
var that = this;
}
This constructor makes three private instance variables: param, secret, and that. They are attached to the object, but they are not accessible to the outside, nor are they accessible to the object's own public methods. They are accessible to private methods. Private methods are inner functions of the constructor.
You can find more details on this link.
The (currently draft) ECMAScript 2022 Specification includes the concept of private identifiers. See Private class features on MDN:
Class fields are public by default, but private class members can be created by using a hash # prefix. The privacy encapsulation of these class features is enforced by JavaScript itself.
Most popular JS engines already support it.
Example:
class Animal {
#owner;
constructor(name, owner) {
this.name = name;
this.#owner = owner;
}
hasOwner() {
return Boolean(this.#owner);
}
}
let dog = new Animal("blacky", "trincot");
console.log(dog.hasOwner()); // true
console.log("#owner" in dog, "#owner" in Animal.prototype); // false, false

Categories

Resources