Scope Chain in Titanium - javascript

I'm whondering how to access a specific method in a widget, which I've created.
var foo = {
init : function() {
$.bar.addEventListener('click', this.handleClick);
},
handleClick : function(e) {
console.log(this); // TiUIButton { widgetId="Ti.UI.Button:0" ...
// I want to call baz() here....How to do that?
},
baz: function() {
}
};
foo.init()
Greetings from germany and thanks for your help,
--marc

Pretty straightforward:
var foo = {
init : function() {
$.bar.addEventListener('click', this.handleClick);
},
handleClick : function(e) {
console.log(this); // TiUIButton { widgetId="Ti.UI.Button:0" ...
// I want to call baz() here....How to do that?
// Like this
foo.baz();
},
baz: function() {
}
};
foo.init()

Related

javascript using this in a child method

Method:
a = {
foo: 1,
bar() {
return this.foo + 1
},
lol: {
baz() {
return this.foo
}
}
}
a.bar() this which refers to a which is what I want. I'm looking for a way for the child method inside a.lol.baz to also have this refer to a. Is there anyway to do it?
You can't refer to it directly. But you can bind the function to the object explicitly, then this will be available.
a = {
foo: 1,
bar() {
return this.foo + 1
},
lol: {}
}
a.lol.baz = (function() {
return this.foo
}).bind(a);
console.log(a.lol.baz());
you can use a.lol.baz.call(a) function
a = {
foo: 1,
bar() {
return this.foo + 1
},
lol: {
baz() {
return this.foo
}
}
}
var res=a.lol.baz.call(a)
alert(res)

Vue.js inheritance call parent method

Is it possible to use method overriding in Vue.js?
var SomeClassA = Vue.extend({
methods: {
someFunction: function() {
// ClassA some stuff
}
}
});
var SomeClassB = SomeClassA.extend({
methods: {
someFunction: function() {
// CALL SomeClassA.someFunction
}
}
});
I want to call ClassA someFunction from ClassB someFunction. Is it even possible?
No, vue doesn't work with a direct inheritance model. You can't A.extend an component, as far as I know. It's parent-child relationships work mainly through props and events.
There are however three solutions:
1. Passing props (parent-child)
var SomeComponentA = Vue.extend({
methods: {
someFunction: function () {
// ClassA some stuff
}
}
});
var SomeComponentB = Vue.extend({
props: [ 'someFunctionParent' ],
methods: {
someFunction: function () {
// Do your stuff
this.someFunctionParent();
}
}
});
and in the template of SomeComponentA:
<some-component-b someFunctionParent="someFunction"></some-component-b>
2. Mixins
If this is common functionality that you want to use in other places, using a mixin might be more idiomatic:
var mixin = {
methods: {
someFunction: function() {
// ...
}
}
};
var SomeComponentA = Vue.extend({
mixins: [ mixin ],
methods: {
}
});
var SomeComponentB = Vue.extend({
methods: {
someFunctionExtended: function () {
// Do your stuff
this.someFunction();
}
}
});
3. Calling parent props (parent-child, ugly)
// In someComponentB's 'someFunction':
this.$parent.$options.methods.someFunction(...);
In case someone's interested in a JustWorksTM solution:
var FooComponent = {
template: '<button #click="fooMethod()" v-text="buttonLabel"></button>',
data: function () {
return {
foo: 1,
bar: 'lorem',
buttonLabel: 'Click me',
}
},
methods: {
fooMethod: function () {
alert('called from FooComponent');
},
barMethod: function () {
alert('called from FooComponent');
},
}
}
var FooComponentSpecialised = {
extends: FooComponent,
data: function () {
return {
buttonLabel: 'Specialised click me',
zar: 'ipsum',
}
},
methods: {
fooMethod: function () {
FooComponent.methods.fooMethod.call(this);
alert('called from FooComponentSpecialised');
},
}
}
jsfiddle: https://jsfiddle.net/7b3tx0aw/2/
More info:
This solution is for devs that can't use TypeScript for some reason (which I think allows defining vue components as classes, which in turn allows full inheritance feature-set).
Further elaboration about the solution (whys and hows): https://github.com/vuejs/vue/issues/2977
This ain't that ugly, considering that no rocket science is used here (calling anonymous functions with the this pointer replaced should be no magic for any decent js dev).
How to use Function.prototype.call()
Reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
Sample code:
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
console.log(new Food('cheese', 5).name);
// expected output: "cheese"
In case someone asks for a solution here is mine and works fine :
var SomeClassA = {
methods: {
someFunction: function () {
this.defaultSomeFunction();
},
// defaultSomeFunction acts like parent.someFunction() so call it in inheritance
defaultSomeFunction: function () {
// ClassA some stuff
},
},
};
var SomeClassB = {
extends: SomeClassA,
methods: {
someFunction: function () {
// Replace the wanted SomeClassA::someFunction()
this.defaultSomeFunction();
// Add custom code here
},
},
};
using juste extends from https://v2.vuejs.org/v2/api/#extends replaces the usage of Vue.extends()

How to pass a function of an object from a function inside a function of the same object?

Mouthful. Ok so this is the sample.
I need to pass bar1 from bar2 inside a function.
var foo = {
bar1 : function () {
},
bar2 : function () {
return function () {
// bar1(); pass bar1 through here ... this.bar1 ?
}
}
You can save this in variable like this:
var foo = {
bar1 : function () {
},
bar2 : function () {
var self = this;
return function () {
self.bar1();
}
}
};
or use bind:
var foo = {
bar1 : function () {
},
bar2 : function () {
return function () {
this.bar1();
}.bind(this);
}
};

Use of functions between inner object literals in javascript

My issue is I have 2 inner objects in my js class and I'm trying to use the methods from one of those objects in my other object (examples of what I'm trying to do below). I understand why this doesn't work because of a the scope. I'm just wondering if there is a way to get it to work.
var Class1 = {
self : this,
Obj1 : {
Obj1Method : function () {
alert("Do something");
},
Obj1Method2 : function () {
alert("Do something else");
},
InnerObj1 : {
InnerNestObj1Method : function (val) {
alert(val + 2);
}
}
},
Class1Method2 : function () {
this.Obj1.Obj1Method2();
},
Obj2 : {
Obj2Method : function (val2) {
self.Obj1.InnerObj1.InnerNestObj1Method(val2);
},
Obj2Method2 : function () {
self.Class1Method2();
}
}
};
Class1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
Class1.Class1Method2(); //works
Class1.Obj2.Obj2Method2(); //No bueno
Class1.Obj2.Obj2Method(5); //No bueno
You can fix your example by replacing self with Class1.
The line self : this, is setting Class1.self to point to the global object (this when that line is evaluated).
var Class1 = {
self : this,
Obj1 : {
Obj1Method : function () {
alert("Do something");
},
Obj1Method2 : function () {
alert("Do something else");
},
InnerObj1 : {
InnerNestObj1Method : function (val) {
alert(val + 2);
}
}
},
Class1Method2 : function () {
this.Obj1.Obj1Method2();
},
Obj2 : {
Obj2Method : function (val2) {
Class1.Obj1.InnerObj1.InnerNestObj1Method(val2);
},
Obj2Method2 : function () {
Class1.Class1Method2();
}
}
};
Class1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
Class1.Class1Method2(); //works
Class1.Obj2.Obj2Method2(); //bueno
Class1.Obj2.Obj2Method(5); //bueno
What happens when you do self: this
// If this is running in non strict mode, from the global scope, `this` points
// To the global object because there was no function call setting `this`
var Class1 = {
self : this,
};
What you need to understand is that this is set by whoever called the function using this. In the example above, there is no caller, so the runtime sets this to point to the global object.
Here's how you could you could make your object a bit more reusable and give yourself a reference to the outer object:
function createClass() {
var self = {
Obj1: {
Obj1Method: function() {
alert("Do something");
},
Obj1Method2: function() {
alert("Do something else");
},
InnerObj1: {
InnerNestObj1Method: function(val) {
alert(val + 2);
}
}
},
Class1Method2: function() {
self.Obj1.Obj1Method2();
},
Obj2: {
Obj2Method: function(val2) {
self.Obj1.InnerObj1.InnerNestObj1Method(val2);
},
Obj2Method2: function() {
self.Class1Method2();
}
}
};
return self;
}
var Class1 = createClass();
Class1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
Class1.Class1Method2(); //works
Class1.Obj2.Obj2Method2(); //works
Class1.Obj2.Obj2Method(5); //works
You can do it with Classes:
"use strict"
class Class1 {
constructor() {
this.Obj1 = {
Obj1Method: function() {
alert("Do something");
},
Obj1Method2: function() {
alert("Do something else");
},
InnerObj1: {
InnerNestObj1Method: function(val) {
alert(val + 2);
}
}
};
var self = this;
this.Obj2 = {
Obj2Method: function(val2) {
self.Obj1.InnerObj1.InnerNestObj1Method(val2);
},
Obj2Method2: function() {
self.Class1Method2();
}
};
}
Class1Method2() {
this.Obj1.Obj1Method2();
}
};
var c1 = new Class1();
c1.Obj1.InnerObj1.InnerNestObj1Method(3); //works
c1.Class1Method2(); //works
c1.Obj2.Obj2Method(3); //works
c1.Obj2.Obj2Method2(); //works

How to call a javascript function inside another function

I have something like this:
var yourNamespace = {
foo: function() {
.....
},
bar: function() {
function foobar() {....
}
}
};
Is there a possibility to call inside of foo, the foobar function inside of bar?
With your exact structure you cannot however you can do something like that :
var yourNamespace = {
foo: function() {
.....
yourNamespace.foobar()
},
bar: function() {
function foobar() {....}
yourNamespace.foobar = foobar;
}
};
Or nicer, (IMO) :
var yourNamespace = {
foo: function() {
.....
yourNamespace.bar.foobar()
},
bar: function() {
yourNamespace.bar.foobar = function() {....}
}
};
Please note: in both case, bar() must run before foo() otherwise foobar is undefined
This is just a simple Module pattern. What you should do is make bar it's own module, and return foobar from that module. Example:
var yourNamespace = {
foo: function() {
this.bar.foobar();
},
bar: {
abc: '',
foobar: function() {
console.log('do something');
}
}
};
Or you could do something more like this:
var yourNamespace = {
foo: function() {
var bar = this.bar();
},
bar: function() {
var abc = '';
function foobar() {
console.log('return abc or do something else');
return abc;
}
return {
foobar: foobar
}
}
};

Categories