How to reference proprerty from sub objects with "this" keyword - javascript

i have to call a property in "object1" from sub object "object3", but this example doesn't work because the "this" keyword is referenced in "object2" and not "object1", do you know how to do this ?
function object1() {
this.a = "hello world";
this.object2 = function() {
this.object3 = function() {
alert(this.a); //prints "undefined"
}
};
}
try this example with:
var obj1 = new object1();
var obj2 = new obj1.object2();
obj2.object3();
thank you in advance :-)

function object1() {
this.a = "hello world";
var self = this;
this.object2 = function () {
this.object3 = function () {
alert(self.a); //prints "undefined"
}
};
}
var obj1 = new object1();
var obj2 = new obj1.object2();
obj2.object3();
You have to store the this object, otherwise you will be accessing the this of the function this.object3's scope

this changes as scope changes. You need to save a reference of this for any new scope:
function object1 () {
var first_scope = this;
this.a = "hello world";
this.object2 = function() {
var second_scope = this;
this.object3 = function() {
var third_scope = this;
alert(first_scope.a);
}
};
}

Related

Why does javascript closure returns [Function (anonymous)]?

Code from medium,understand closures
function Person(name) {
var secret = 'secret!';
this.name = name
this.setName = function(newName) { this.name = newName }
this.setNameToFoo = function() { this.name = foo }
this.getSecret = function() { return secret }
}
var a = new Person('Max');
console.log(a.name);
a.setName('Oliver')
console.log(a.name);
var foo = 'Foo';
a.setNameToFoo()
console.log(a.name);
console.log(a.getSecret);
Output
Max
Oliver
Foo
[Function (anonymous)]
Everything is OK,except the last one. It seems that local bindings is not visible.
Why?
At the last line you are not calling the function. It should be console.log(a.getSecret());
function Person(name) {
var secret = 'secret!';
this.name = name
this.setName = function(newName) { this.name = newName }
this.setNameToFoo = function() { this.name = foo }
this.getSecret = function() { return secret }
}
var a = new Person('Max');
console.log(a.name);
a.setName('Oliver')
console.log(a.name);
var foo = 'Foo';
a.setNameToFoo()
console.log(a.name);
console.log(a.getSecret());
You're getting this error because you're displaying the function itself in console.log, not its returning value.
Fix: Replace your last line with this one
console.log(a.getSecret());

How can I reference the parent object in a child function?

Given an object like this:
var MyObj = {
bar: 10,
foo: function() {
alert(MyObj.bar);
}
}
How can I generically reference MyObj from MyObj.foo such that if I were to change var MyObj to var MyObj2 I wouldn't need to modify the foo function?
If you want to treat MyObj like a class, you could do something like what lumio suggested, or you could do something like
function MyObj(){
this.bar = 10;
this.foo = function(){
return this.bar;
}
}
var a = new MyObj();
var b = new MyObj();
b.bar = 5;
console.log(a.foo(), b.foo()) // 10 5
If instead, you just want to reference the object's bar value, then you could just replace the alert(MyObj.bar); with alert(this.bar);
Classes would help you a lot here. In ES5 classes can be created like so:
function MyObj() {
this.bar = 10;
}
MyObj.prototype.foo = function() {
console.log( this.bar );
}
var objInstance = new MyObj;
objInstance.foo();
var objInstance2 = new MyObj;
objInstance2.bar = 20;
objInstance2.foo();
ES6 allows an even better notation:
class MyObj {
constructor() {
this.bar = 10;
}
foo() {
console.log( this.bar );
}
}
var objInstance = new MyObj;
objInstance.foo();
var objInstance2 = new MyObj;
objInstance2.bar = 20;
objInstance2.foo();
Use babel to convert it to ES5.

javascript access "this" in function constructor

I'm trying to create a function constructor:
var obj = function() {
this.num = 2;
this.func = function() {
// need to access the **instance** num variable here
};
};
var instance = new obj();
I need to access the instance properties from a propery (which is the function func) of the object. But it doesn't work, since this is always the current function..
Store this in a variable which func can access:
var obj = function() {
var _this = this;
_this.num = 2;
_this.func = function() {
console.log(_this.num);
};
};
Please, use well-known approach, store this into separate field:
var obj = function() {
self = this;
self.num = 2;
self.func = function() {
alert(self.num);
// need to access the **instance** num variable here
};
};
var instance = new obj();
This is the pattern I use for the problem:
var obj = function(){
var self = this;
this.num = 2;
this.func = function() {
console.info(self.num);
};
};
var instance = new obj();
The variable self now can be accessed in all function of obj and is always the obj itself.
This is the same then:
var obj = function(){
var self = this;
self.num = 2;
self.func = function() {
console.info(self.num);
};
};
var instance = new obj();
You can do it using the Custom Constructor Functions, used to create a custom constructor and it's accessed without any problem, try it:
var Obj = function () {
this.num = 2;
this.func = function () {
alert("I have " + this.num);
return "I have " + this.num;
};
};
var instance= new Obj();
instance.func();//will return and show I have 2

What is the best way to access to "this" inside a sub object in javascript class?

This doesn't work because f.bar.bar() in undefined.
var myFunction = function(foo){
this.foo = foo;
this.bar = {
bar: function(){
return this.foo;
}
}
}
var f = new myFunction('foo');
alert(f.bar.bar());
You can always declare a variable in the parent scope:
var myFunction = function(foo){
var func = this;
this.foo = foo;
this.bar = {
bar: function(){
return func.foo;
}
}
}
var f = new myFunction('foo');
alert(f.bar.bar());

Managing this scope in javascript

I am trying to get this function to get the correct scope for its "this" operator, but no luck. Inside the AssetName = function(options){ code block, I want the "this" to point to the class AssetName. What is it that I am missing? The scope of this right from the beginning is window.
Assetname: function(options){
var Base = WM.Utility.GenericFilter()
options = options;
if (typeof Object.create !== "function") {
// For older browsers that don't support object.create
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
var AssetName = {};
AssetName = function(options){
return function(){
var self = this;
debugger;
// Call the super constructor.
Base.call(this, options);
this.$mod.on('change', '#asset-name-quick-search', self,
this.search);
this.$mod.on('click', '.close', self, this.remove);
this.initTypeAhead();
this.$selectionList = this.$mod.find("#asset-name-selection-list");
this.assetListItems = [];
return this;
}(options, AssetName);
}
// The AssetName class extends the base GenericFilter class.
AssetName.prototype = Object.create(Base.prototype);
AssetName.prototype.initTypeAhead = function(){
var options = {};
options.source = _.pluck(this.collection, 'asset_name');
options.items = 8;
this.$mod.find('#asset-name-quick-search').typeahead(options);
};
AssetName(options);
return AssetName;
},
AssetName = function(options){
return function(){
var self = this;
debugger;
// Call the super constructor.
Base.call(this, options);
this.$mod.on('change', '#asset-name-quick-search', self, this.search);
this.$mod.on('click', '.close', self, this.remove);
this.initTypeAhead();
this.$selectionList = this.$mod.find("#asset-name-selection-list");
this.assetListItems = [];
return this;
}(options, AssetName);
}
change to
AssetName = function(options){
var aa = function(){
var self = this;
debugger;
// Call the super constructor.
Base.call(this, options);
this.$mod.on('change', '#asset-name-quick-search', self, this.search);
this.$mod.on('click', '.close', self, this.remove);
this.initTypeAhead();
this.$selectionList = this.$mod.find("#asset-name-selection-list");
this.assetListItems = [];
return this;
};
aa.call(AssetName,options);
}
In your code, the function aa is called as aa(options); so this is window.
[update]
I fix the bug with the following code:
AssetName = function (options) {
AssetName = function (options) {
var aa = function () {
alert(this);
return this;
};
aa.call(this, options);
}
AssetName.prototype.initTypeAhead = function () {
alert(1);
}
return new AssetName(options);;
};
var test = AssetName();
test.initTypeAhead();
But I suggest how about writing the code like bellow:
AssetName = function (options) {
AssetName = function (options) {
alert(this);
}
AssetName.prototype.initTypeAhead = function () {
alert(1);
}
return new AssetName();
};
var test = AssetName();
test.initTypeAhead();
You cam just move your var self = this out side of the anonymous returned function. Then you can use just use self.

Categories

Resources