Memory leak example - javascript

Explain please step by step a reason of memory leak in the following part of code:
var theThing = null;
var replaceThing = function () {
var priorThing = theThing; // hold on to the prior thing
var unused = function () {
// 'unused' is the only place where 'priorThing' is referenced,
// but 'unused' never gets invoked
if (priorThing) {
console.log("hi");
}
};
theThing = {
longStr: new Array(1000000).join('*'), // create a 1MB object
someMethod: function () {
console.log(12);
}
};
};
setInterval(replaceThing, 10);

Related

Javascript Protractor - Seeing outside functions as undefined

In specs/Test.js is a test definition: "regex2"
In pages/TablePage.js is a page object
in regex2 there is a try to use a function from TablePage.js
it('regex2', function(){
table_page.matchPriceRegex(table_page.workingBalanceField)
});
it is saying table_page.matchPriceRegex is not a function
The function itself from TablePage.js:
var TablePage = (function () {
function TablePage() {
this.workingBalanceField = element(By.xpath('//*[#id="root"]/main/section/div/div/div[5]/div/div[1]'));
}
TablePage.prototype.matchPriceRegex = function (locator) {
this.text = locator.getText();
expect(this.text).toMatch("\d{0,3}?,?\d{0,3}?\.?\d{0,3}?");
};
});
module.exports = TablePage;
The require's are incorporated with the spec file so it should see it
var TablePage = require("./../pages/TablePage");
var table_page = new TablePage();
var protractor = require("protractor");
var jasmine = require("jasmine-node");
var browser = protractor.browser;
var number = 0;
When in my IDE(WebStorm) I hold ctrl and click on the function name it redirects me correctly, as it sees it
The typeof the functions or variables form TablePage is undefined
Do you know where is the problem?
The error comes from TablePage.js, it should be.
var TablePage = (function () {
function TablePage() {
this.workingBalanceField = element(By.xpath('//*[#id="root"]/main/section/div/div/div[5]/div/div[1]'));
}
TablePage.prototype.matchPriceRegex = function (locator) {
this.text = locator.getText();
expect(this.text).toMatch("\d{0,3}?,?\d{0,3}?\.?\d{0,3}?");
};
return TablePage; // return the class as outer function return value
})();
// `(function(...){})` return a function, you should use `()` to execute the
// return function to get the returned class: TablePage.
module.exports = TablePage;

Scope Regarding "use strict" and $this

I have the following code
$(document).ready(function($) {
"use strict";
generalClass = function() {
this.ip = false; // page page
this.ie = false; // IE
this.pp = false; // portfolio page
this.om = false; // organize menu
this.wc = false; // shop
this.sh = false; // side header
// So we can get the correct $this if needed
$this = this;
this.__init();
}
generalClass.prototype = {
__init: function( $check ) {
// Run functions
$this.__format();
$this.__resize();
}
}
});
But I am getting that $this is undefined. I have tried writing it as var $this but still it is undefined for $this.__format();. I realise that I can use this instead of $this, but there are instances later in the code where I can't. How do I make it so that $this is defined in the __init() function? So that it refers to generalClass.
Thanks!
First of all, if you want to use strict-mode, then you have to put var (or let, or const) before your generalClass and $this.
Like that:
(function () {
"use strict";
var generalClass = function() {
this.ip = false; // page page
this.ie = false; // IE
this.pp = false; // portfolio page
this.om = false; // organize menu
this.wc = false; // shop
this.sh = false; // side header
// So we can get the correct $this if needed
var $this = this;
this.__init();
};
generalClass.prototype = {
__init: function( $check ) {
console.log('$this', $this);
// Run functions
$this.__format();
$this.__resize();
}
}
var instance = new generalClass();
}());
(I changed $(document).ready() to IIFE so I could run it in console. Plus, I created instance of your class.)
What happens now? $this inside __init() is not defined. You would have to define $this inside __init() but here is the problem: what should be assigned to it?
In your example of __init() you could actually call this instead of $this but as you already pointed it’s not always possible.
But let me illustrate it with more abstract example:
(function () {
var GeneralClass = function () {
this.foo = [1, 2, 3];
this.bar = 4;
this.baz = [5];
};
GeneralClass.prototype.someFunction = function () {
console.log('foo', this.foo); // [1, 2, 3]
console.log('bar', this.bar);
var self = this; // storing reference to *this* (oobject for later)
this.baz.forEach(function (item) {
console.log('baz?', this.baz); // undefined, because *this* means here this.baz, and there is no this.baz.baz
console.log('baz!', self.baz); // [5]
});
console.log('foo * bar');
this.foo.forEach(function (item, index) {
console.log('item', index, 'value', item * self.bar);
});
console.log('Both accesible here', this.bar, self.bar);
};
var generalClassInstance = new GeneralClass();
generalClassInstance.someFunction();
}());
Here I assign this to self (personally, I’d use $this for $(this) but it’s only a convention so do as you please, as long as you are consistent). Now functions called inside my function can use self which works as a reference to outer this. And if I called another function in my sub-function, it would still point to GeneralClass’s this.
I hope this is what you were primarily interested in.

How do i share my World instance across multiple step definition files in CucumberJS?

I am implementing a CucumberJS scenario which uses multiple steps across two different step definition files. The first step sets some variables on the World which have to be used by a step in the other step definition file.
The variable gets set correctly but when the step on the other file tries to read it it's undefined. Any ideas how to solve this apart from merging the step definition files?
example:
world.js
var World = function World() {
this.client = '';
};
module.exports.World = World;
test.feature
Given a variable A
Then some other step
step1.steps.js
module.exports = function () {
this.World = require(process.cwd() + '/test/features/support/world').World;
this.Given(/^a Variable A$/, function () {
this.client = 'abc';
});
};
step2.steps.js
module.exports = function () {
this.World = require(process.cwd() + '/test/features/support/world').World;
this.Then(/^some other step$/, function () {
console.log(this.client);
});
};
You are setting this.client instead of this.World.client. Moreover you should use an object and not a constructor in world.js:
world.js
module.exports = {
client: ''
};
step1.steps.js
var world = require('./test/features/support/world.js');
module.exports = function () {
this.Given(/^a Variable A$/, function () {
world.client = 'abc';
});
};
step2.steps.js
var world = require('./test/features/support/world.js');
module.exports = function () {
this.Then(/^some other step$/, function () {
console.log(world.client);
});
};
You could directly parameterise your test.feature :
Given a variable "abc"
Then some other step
now pass this variable in your step
step1.steps.js
module.exports = function() {
this.World = require(process.cwd() + '/test/features/support/world').World;
this.Given(/^a Variable "([^"]*)"$/, function(variable) {
this.client = variable;
});
};
step2.steps.js
module.exports = function() {
this.World = require(process.cwd() + '/test/features/support/world').World;
this.Then(/^some other step$/, function() {
console.log(this.client); // would print abc
});
};

test new object instance (jasmine)

I have tests run by karma, in one of them I create new instance of object and call function where is used this. On normal browser this is reference to current instance but in test after console.log it I see:
Object{document: < !-- This is the execution context.
Loaded within the iframe. Reloaded before every execution run.
Why?
// createing the object
window.gr = window.gr || {};
gr.Notification = (function () {
function Notification(node, message) {
this.liveTime = 5000;
this.template = this.createTemplate(message);
this.node = null;
this.appendTo(node);
setTimeout(this.remove, this.liveTime);
}
Notification.prototype = {
createTemplate: function (message) {
var notification = document.createElement("div");
notification.className = "notification";
var _message = document.createTextNode(message);
notification.appendChild(_message);
return notification;
},
appendTo: function(node){
this.node = node.appendChild(this.template);
},
remove: function(){
console.log(this)
this.node.parentNode.removeChild(this.node);
}
};
return Notification;
})();
//test
beforeEach(function(){
Notification = gr.Notification;
jasmine.clock().install();
});
it("should remove notification after 5s", function(){
new Notification(document.body);
jasmine.clock().tick(5001);
expect(document.querySelectorAll(NOTIFICATION_SELECTOR).length).toEqual(0);
});
your this references to window, because you call setTimeout, which is method of window object, so this inside that method points to window,
you could do something like that:
function Notification(node, message) {
this.liveTime = 5000;
this.template = this.createTemplate(message);
this.node = null;
this.appendTo(node);
var self = this;
setTimeout(function() {
self.remove()
}, self.liveTime);
}

Multiple variable declarations to add the reference to parent object

As a sample,
I have a object it has the huge no of methods. each method as it own private functions. when i require to refere my object parent, usually i do like this:
var that = this - it works fine.
But in case of huge number is there a way to avoid this?
example:
var x = function () {
return {
init:function () {
this.val = 10;
},
fun1 : function () {
var that = this;
var p = function () {
console.log(this.val) //not works i know
console.log(that.val) //not works
}
},
fun2 : function () {
var that = this;
var p = function () {
console.log(this.val) //not works i know
console.log(that.val) //not works
}
},
fun3 : function () { // it keep grow to 100's..!?
var that = this;
var p = function () {
console.log(this.val) //not works i know
console.log(that.val) //not works
}
}
}
}();
x.init();
Live

Categories

Resources