How to create a new object from an existing one? - javascript

This doesn't work, and I have no idea how to fix it
function bar() {...}
function foo() {
this = new bar();
this.newfunction = function() {...};
this.newvalue = "foobar";
}
var foobar = new foo();
Thanks in advance,

Do not use this to represent another object.
function bar() {...}
function foo() {
var bar = new bar();
bar.newfunction = function() {...};
bar.newvalue = "foobar";
}
var foobar = new foo();

Are you trying to inherit from bar? Then you can borrow its constructor and all its own properties using call (or apply):
function bar() {...}
function foo() {
bar.call(this);
this.newfunction = function() {...};
this.newvalue = "foobar";
}
var foobar = new foo();

Related

get function execution context

I have a function foo:
function foo() {
return 'foo';
}
While foo got executed is there a way to know if foo was called inside object declaration ? I want to distinguish these two cases:
var bar = {
prop1: foo()
}
var var1 = foo();
Here's one approach demonstrating the suggestions in the comments and assuming you'd rather call bar.prop1 instead of bar.prop1().
function foo (ctx) {
console.log(ctx == window)
return 'foo'
}
class Bar {
get prop1() {
return foo(this)
}
}
var var1 = foo(this);
var bar = new Bar();
bar.prop1;

How to call function from object

I try to call function from object Foo but it doesn't work.
function Foo(){
function bar(){
alert("Hello!");
}
}
var a = new Foo();
a.bar();
you should set the function as object's property
function Foo(){
this.bar = function (){
alert("Hello!");
};
}
var a = new Foo();
a.bar();
or use prototype to define it before object creation
function Foo(){}
Foo.prototype.bar = function (){
alert("Hello!");
};
var a = new Foo();
a.bar();
In addition to #user3896501's answer,
function Foo() {
// You can define all private variables/ functions.
function bar(callBar1) {
alert("Hello!");
if (callBar1)
bar1();
}
// This is a private function and can be called only from inside.
function bar1() {
alert("Hello!!!");
}
// Return only those variables/ functions which needs to be made public
return {
bar: bar
}
}
var a = new Foo();
a.bar();
// Trying to access private function should throw exception
try {
a.bar1();
} catch (e) {
console.log(e)
}
// Accessing private function using parameter
a.bar(true);
function Foo()
{
// ...
}
Foo.prototype.bar = function ()
{
alert("I called bar on a Foo object");
};
var a = new Foo();
a.bar();
function Foo(){
function bar(){
alert("Hello!");
}
return {
bar : bar
}
}
var a = new Foo();
a.bar();

Can I save object prototype in local storage?

I have JS object with custom methods as prototype (e. g. Foo.prototype.myAwesomeMethod). If I load my object in a localStorage and get it later I'll loose these methods.
var foo = new Foo()
console.log(foo.myAwesomeMethod()) // WIN
localStorage.setItem('foo', foo)
foo = localStorage.getItem('foo')
console.log(foo.myAwesomeMethod()) // FAIL...
Is it possible to save the prototype of the object in the localStorage ? If not, how to properly re-instantiate the class?
you can try this
function Foo() {
this.bar = 1;
}
Foo.prototype.myAwesomeMethod = function () {
return "And the winner is " + this.bar;
}
var foo;
window.onload = function () {
foo = new Foo();
foo.bar = 3;
console.log(foo.myAwesomeMethod()); // "And the winner is 3"
var test = JSON.stringify(foo); //localStorage.setItem('foo', foo);
foo = JSON.parse(test); // = localStorage.getItem('foo');
foo.__proto__ = new Foo(); // <--------------
console.log(foo.myAwesomeMethod()); // "And the winner is 3"
});
EDIT:
my previous code was untested and didn't work, this is the working code

Change function in function

I have ready code something like this and
I can't change function Foo() because it's alias framework.
function Foo(){
this.prop = {
width: 200
}
this.do = function(s1,s2){
alert(s1+s2);
}
}
I need change do function.
After function Foo() and before var foo1 = new Foo(); foo1.do(1,0); I try write
Foo.do = function(){
alert('changed');
}
I can't change do function. I used defineProperty and even constructor) I haven't prototype.
Full uncorrect demo code
function Foo(){
this.prop = {
width: 200
}
this.do = function(s1,s2){
alert(s1+s2);
}
}
Foo.do = function(){
alert('changed');
}
var foo1 = new Foo();
foo1.do(1,0);
var foo2 = new Foo();
foo2.do(1,1);
var foo3 = new Foo();
foo3.do(1,2);
I can change it for foo1, foo2 and etc. I need cange it ine time.
I'd suggest creating your own constructor that implements Foo.
function Foo() {
this.prop = {
width: 200
}
this.do = function (s1, s2) {
console.log(s1 + s2);
}
}
Foo.prototype.someMethod = function () {};
// can't change any of the above..
function MyFoo() {
Foo.call(this);
this.oldDo = this.do;
this.do = function (s1, s2, s3) {
// do something else!
console.log(s1 + s2 + s3);
}
}
MyFoo.prototype = Object.create(Foo.prototype);
// tests...
var foo = new Foo();
foo.do(2, 2, 2); // 4
console.log(foo.prop.width); // 200
var myFoo = new MyFoo();
myFoo.do(2, 2, 2); //6
console.log(myFoo.prop.width); // 200
Your new constructor only has to override the methods you want to change, the rest will stay the same and the original isn't changed. Notice how instances of MyFoo also have a .prop property even though that was done in Foo's constructor, not MyFoo.
newDo = function(){}; // your new do function
var foo1 = new Foo()'
foo1.do = newDo;
foo1.do(1,0)
and so on. If you can't change the Foo function, and you can't restrict yourself to ES6 or Firefox (they have ways to modify the prototype), then the best option is to overwrite do after creating a new Foo.
This is also a good point to plug learning the module pattern so that you can create your own nested versions of things:
function Foo() {}; //your original foo
(function() {
function Foo() {}; //your new foo with a new do method
// do stuff with the modified do here
})()

How to get 'this' value of caller function?

If I have a function like this:
function foo(_this) {
console.log(_this);
}
function bar() {}
bar.prototype.func = function() {
foo(this);
}
var test = new bar();
test.func();
then the test instance of bar gets logged.
However, for this to work I have to pass the this in the bar.prototype.func function. I was wondering whether it is possible to obtain the same this value without passing this.
I tried using arguments.callee.caller, but this returns the prototype function itself and not the this value inside the prototype function.
Is it possible to log the test instance of bar by only calling foo() in the prototype function?
If the question is 'without passing this (by any means)' then answer is no
value can be passed by alternative methods though. For example using global var (within Bar class) or session or cookies.
function bar() {
var myThis;
function foo() {
console.log(myThis);
}
bar.prototype.func = function() {
myThis = this;
foo();
}
}
var test = new bar();
test.func();
I think calling foo within the context of bar should work:
function foo() {
console.log(this.testVal);
}
function bar() { this.testVal = 'From bar with love'; }
bar.prototype.func = function() {
foo.call(this);
}
var test = new bar();
test.func(); //=> 'From bar with love'
You can do this without changing the external function, but you must change the way you call it.
You can't get the context of the caller, but you can set the this property on a function you call with the method apply or call. See this reference for an explanation on this.
function foo()
{
console.log( this );
}
function bar()
{
bar.prototype.func = function func()
{
foo.apply( this );
};
}
var test = new bar();
test.func();
Usually if this is used, it's in an object oriented context. Trying to call a method of an object with another this might indicate poor design. Explain a bit more what you are trying to achieve for more applicable design patterns.
For an example of a javascript OOP paradigm, check my answer here.
What about this?
"use strict";
var o = {
foo : function() {
console.log(this);
}
}
function bar() {}
bar.prototype = o;
bar.prototype.constructor = bar;
bar.prototype.func = function() {
this.foo();
}
var test = new bar();
test.func();
Or this:
"use strict";
Function.prototype.extender = function( o ){
if(typeof o == 'object'){
this.prototype = o;
}else if ( typeof o == 'function' ) {
this.prototype = Object.create(o.prototype);
}else{
throw Error('Error while extending '+this.name);
}
this.prototype.constructor = this;
}
var o = {
foo : function() {
console.log(this);
}
}
function bar() {}
bar.extender(o);
bar.prototype.func = function() {
this.foo();
}
var test = new bar();
test.func();

Categories