This question already has answers here:
Add a line of code to ALL functions
(3 answers)
Closed 8 years ago.
I currently have a function which I call at the end in several other functions. Instead of writing it like this:
function foo(){
baz();
}
function bar(){
baz();
}
function baz(){
}
Is there any way to make baz() run automatically when calling the funcions? Perhaps by modifying the prototype of the other functions and add it as an IIFE? Is this possible?
Do you mean something like "Template method" design pattern. If so, try this:
function inherit(proto) {
var F = function() { };
F.prototype = proto;
return new F();
}
var template = {
process: function() {
this.mainfunction();
this.baz();
}
baz:function(){
}
};
(function run() {
var foo = inherit(template);
foo.mainfunction = function(){
}
foo.process();
var bar = inherit(template);
bar.mainfunction = function(){
}
bar.process();
}())
Related
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 4 years ago.
Consider this simple TS script
class foo {
v: number = 1;
public bar() {
console.log(this.v);
}
}
var a = new foo();
var b = new foo();
document.getElementById('test').addEventListener("click", a.bar);
document.getElementById('test').addEventListener("click", b.bar);
and the HTML
<html lang="en">
<body>
<button id="test">Test</button>
</body>
</html>
I would expect to get 2 lines console output of number "1".
But NO! I get one undefined output
Lets take a look at the generated js file
var foo = (function () {
function foo() {
this.v = 1;
}
foo.prototype.bar = function () {
console.log(this.v);
};
return foo;
}());
var a = new foo();
var b = new foo();
document.getElementById('test').addEventListener("click", a.bar);
document.getElementById('test').addEventListener("click", b.bar);
//# sourceMappingURL=Test.js.map
For performance consideration TS decided to put the function on the prototype! so the addEventListener call was actually adding the prototype (static) function twice and its the same instance. That's why I'm only getting one output instead of two.
And the biggest issue is that the this inside the prototype function refers to the button and button doesn't contain a property called v!
If we do this in native js
var foo = function () {
this.v = 1;
var that = this;
this.bar = function () {
console.log(that.v);
}
}
var a = new foo();
var b = new foo();
document.getElementById('test').addEventListener("click", a.bar);
document.getElementById('test').addEventListener("click", b.bar);
we would get the desire result!
Is this a known issue for TS where you can't use the class method as event handler?
And how can I remove that handler after I added it?
You can. Just do:
document.getElementById('test').addEventListener("click", () => a.bar());
This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
class Foo {
constructor() {
this.foobar = "foobar";
}
bar() {
let _this = this;
return function() {
try {
alert("Attempt 1: "+foobar);//ReferenceError: foobar is not defined
myMethod();
} catch(err) {console.log(err);}
try {
alert("Attempt 2: "+this.foobar);//TypeError: this is undefined
this.myMethod();
} catch(err) {console.log(err);}
try{
alert("Attempt 3: "+_this.foobar);//Works!
_this.myMethod();
} catch(err) {console.log(err);}
}();
}
myMethod() {
alert("myMethod()");
}
}
new Foo().bar();
The above example is very simplified - the anonymous function inside bar() was a jQuery call originally, but for the sake of the question I didn't include that.
Why don't attempts 1 and 2 work? Do I have to use the _this trick to reference class variables/methods? How do I reference class variables/methods from nested functions?
Are you familiar with how the this keyword works in JavaScript? It's value will depend on how the function is called, not in how it is defined. For example, if you do the following:
var dog = {
greeting:"woof",
talk:function (){
console.log(this.greeting);
}
};
var cat={
greeting:"meow",
talk:dog.talk
};
dog.talk();
cat.talk();
You will see that when the talk function is called as a method of an object, that object will be used as the value of this.
The same happens with ES6 classes, where class methods are still JavaScript functions and the rules for deciding the value of this still apply. If you want to avoid declaring an auxiliar variable, you should look into using bind:
var mammal = {
greeting:"<noise>",
getTalk:function (){
return function(){
console.log(this.greeting);
};
},
getTalkBinded:function (){
return (function(){
console.log(this.greeting)
}).bind(this);
}
};
var dog={
greeting:"woof",
talk:mammal.getTalk(),
talkBinded:mammal.getTalkBinded()
};
var cat={
greeting:"meow",
talk:mammal.getTalk(),
talkBinded:mammal.getTalkBinded()
};
dog.talk();
cat.talk();
dog.talkBinded();
cat.talkBinded();
You are returning self-execution function execution result and during that function execution this it global context(not your class object). to make it work use () => {}() arrow function call syntax, as it captures current context, or function() { }.bind(this)().
See this simple example,
function a(){
this.someProp = 5;
console.log(this);
var _this = this; //so we explicitly store the value of `this` to use in a nested function
return function(){
//value of `this` will change inside this function
this.anotherProp = 6;
console.log(this);
//to use the methods and props of original function use `_this`
console.log(_this)
}
}
var c = a.call({}) //prints {someProp: 5}
c.call({}) //prints {anotherProps: 6} {someProp: 5}
This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
I have the following code (simplified)
var Page = new UI('page.html');
Page.onLoad = function(html){
this.name = 'Page 1';
Util.test(this.run);
};
Page.run = function(){
console.log(this.name); // undefined
console.log(Page.name); // correct
};
var Util = function(){};
Util.prototype.test = function(callback){
// when finished run the callback
callback();
};
My question is why I can't use the this keyword if the execution leaves the object then comes back? Please explain what should I change to be able to access this again.
You can bind "this" to function run, like this.
Page.onLoad = function(html){
this.name = 'Page 1';
Util.test(this.run.bind(this));
};
You can find more information for function "bind". https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
The top of the article references another post regarding 'this', so, I thought I'd just provide the code. If you read the other post and the articles linked within, you should be able to follow this code.
function UI(html) {
this.name = html;
}
UI.prototype = {
onLoad: function () {
util.test(this);
},
run: function () {
console.log(this.name);
}
}
var util = (function () {
return {
test: function (ui) {
if (ui && ui.run) {
ui.run();
}
}
}
})();
var page = new UI("index.html");
This question already has answers here:
dynamically call local function in javascript
(5 answers)
Closed 8 years ago.
I was wondering if it's possible to call a function by passing a string name. Following is the basic architecture:
Javascript:
"use strict";
function foo(){
var f = this;
f.fn = function(o){return fn(o)}
function fn(o){
o.name();
}
function a(){
alert('a');
}
function b(){
alert('bb');
}
}
var f = new foo();
f.fn({name:'a'});
f.fn({name:'b'});
The code is setup at http://jsfiddle.net/rexonms/9c7bnkc9/.
You can achieve it using eval:
function foo(){
var f = this;
f.fn = function(o){return fn(o)}
function fn(o){
eval(o.name + '()');
}
function a(){
alert('a');
}
function b(){
alert('bb');
}
}
var f = new foo();
f.fn({name:'a'});
f.fn({name:'b'});
Here is jsFiddle: http://jsfiddle.net/9c7bnkc9/2/
This question already has answers here:
var functionName = function() {} vs function functionName() {}
(41 answers)
Closed 9 years ago.
In the Module Pattern example from Addy Osmani, a private function is assigned to a variables as shown in this example:
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
// A public function utilizing privates
myPublicFunction: function( bar ) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod( bar );
}
};
})();
I would have simply written the private function as:
function myPrivateMethod( foo ) {
console.log( foo );
};
Is there any reason to assign the function to a variable if it's not used as a delegate? I'm looking at some code that uses this pattern consistently and I'm finding it hard to follow. For example:
var _initializeContext = function() { // many lines of code }
This is a function declaration vs a function expression issue. To some degree it's a stylistic choice. What you do need to be aware of is that function declarations get hoisted by the JS interpreter, which function expressions aren't. Some people prefer to use function expressions because they don't like the idea of their code being rearranged.
You might want to check out:
var functionName = function() {} vs function functionName() {}
http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/
http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html