How to make local varible global javascript - javascript

I have this class like so :
https://jsfiddle.net/0sh7fLtp/
When I create a new object of this class, my local variable can't be seen even when I assign to window in the class:
function Hilitor() {
var excat;
this.setMatchType = function(type) {
if (type == "exact"){
window.excat = true;
}
};
this.setRegex = function(input) {
alert(excat);
};
this.apply = function(input) {
this.setRegex();
};
}
and this is how i call it :
var myHilitor = new Hilitor();
myHilitor.apply();
myHilitor.setMatchType("exact");

Not sure I completely understand your question but you are trying to compare a variable "excat" to string "excat"... See this fiddle to how you can make your var a string and then get desired output..
https://jsfiddle.net/shemdani/0sh7fLtp/5/
var myHilitor = new Hilitor();
myHilitor.setMatchType("excat");
myHilitor.apply();
function Hilitor()
{
var excat;
this.setMatchType = function(type)
{
if(type == "excat"){window.excat = true;}
};
this.setRegex = function(input)
{
alert(window.excat);
};
this.apply = function(input)
{
this.setRegex();
};
}

Two main problems
1) Your var exact inside the function is not a global variable and so not accessible on the window object. (But that's a good thing).
Your code will work if you remove window.exact for just exact
this.setMatchType = function(type)
{
if(type == "exact"){excat = true;}
};
2) You are also calling apply before you call setMatchType. Switching them like this works:
var myHilitor = new Hilitor();
myHilitor.setMatchType("excat");
myHilitor.apply();
Working example

Related

Javascript & knockoutjs: how to refactor the following code to be able to access the properties outside the function

Im struggling to find a way to get the properties Override & Justification available outside of the function. The code is:
self.CasOverridesViewModel = ko.observable(self.CasOverridesViewModel);
var hasOverrides = typeof self.CasOverridesViewModel === typeof(Function);
if (hasOverrides) {
self.setupOverrides = function() {
var extendViewModel = function(obj, extend) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
extend(obj[property]);
}
}
};
extendViewModel(self.CasOverridesViewModel(), function(item) {
item.isOverrideFilledIn = ko.computed( function() {
var result = false;
if (!!item.Override()) {
result = true;
}
return result;
});
if (item) {
item.isJustificationMissing = ko.computed(function() {
var override = item.Override();
var result = false;
if (!!override) {
result = !item.hasAtleastNineWords();
}
return result;
});
item.hasAtleastNineWords = ko.computed(function() {
var justification = item.Justification(),
moreThanNineWords = false;
if (justification != null) {
moreThanNineWords = justification.trim().split(/\s+/).length > 9;
}
return moreThanNineWords;
});
item.isValid = ko.computed(function() {
return (!item.isJustificationMissing());
});
}
});
}();
}
I've tried it by setting up a global variable like:
var item;
or
var obj;
if(hasOverrides) {...
So the thing that gets me the most that im not able to grasp how the connection is made
between the underlying model CasOverridesviewModel. As i assumed that self.CasOverridesViewModel.Override() would be able to fetch the data that is written on the screen.
Another try i did was var override = ko.observable(self.CasOverridesViewModel.Override()), which led to js typeError as you cannot read from an undefined object.
So if anyone is able to give me some guidance on how to get the fields from an input field available outside of this function. It would be deeply appreciated.
If I need to clarify some aspects do not hesitate to ask.
The upmost gratitude!
not sure how far outside you wanted to go with your variable but if you just define your global var at root level but only add to it at the moment your inner variable gets a value, you won't get the error of setting undefined.
var root = {
override: ko.observable()
};
root.override.subscribe((val) => console.log(val));
var ViewModel = function () {
var self = this;
self.override = ko.observable();
self.override.subscribe((val) => root.override(val));
self.load = function () {
self.override(true);
};
self.load();
};
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

Ways to access an object that triggered a breakpoint?

In chrome console, I have set some breakpoints in code of the sources. Those are set in a class for which an instance of this class was instantiated at loadtime. :
var SearcherBlock = function(n) {
function t() {
n.apply(this, arguments);
this.CurrentData = null;
this.onInput = null;
this.SearchInput = document.getElementById(this.BlockUniqueID + "_SearchInput");
this.SearchResults = document.getElementById(this.BlockUniqueID + "_Search_Results");
this.SearchResultsTitle = document.getElementById(this.BlockUniqueID + "_ResultsTitle");
this.onDocumentClick = this.onDocumentClickHandler.bind(this);
this.MinSearchStringLength = SearchController.getMinSearchStringLength(this.Configuration.LanguagesFor2SymbolSearch)
}
var i = {
destroyed: !0
};
return $.extend(t.prototype, n.prototype),
t.prototype.activate = function() {
n.prototype.activate.call(this);
this.onInput = this.textChange.bind(this);
this.SearchInput && this.SearchInput.addEventListener("input", this.onInput, !1);
this.tooltipsInit()
}
t.prototype.textChange = function(n) {
var t = n.srcElement || n.target;
if (this.SearchResultsTitle.innerHTML) {
... }
}
}
So now when I am at a breakpoint in this class whose instance I would like to achieve is triggered in this class. I would like to figure out a way to access this instance, like window.something.something - how can I do this if possible?
The reason is that when I call the function hasText() by window.hasText(), it complains because all properties of the this that is being used in the function are undefined. Therefore, I would like to have a way of accessing the instantiated object.

Defining a function of an object JavaScript

How do you define a function that is within an object?
var CustomerDB = {customers:[], addresses:[], stores:[], insertData, addCustomer}
CustomerDB.insertData = function (objData){
objData.forEach(function(element){
if (element.type == "customer"){
CustomerDB.addCustomer(element.data);
};
});
};
CustomerDB.addcustomer = function (customerObj){
customerObj.add_date= new Date();
CustomerDB.customers.push(customerObj);
};
CustomerDB.insertData(allData);
console.log(CustomerDB.customers);
I keep getting errors that insertData is not defined. What do I need to do?
insertData and addCustomer are properties of the CustomerDB object, and are not function expressions that you could assign to CustomerDB just like you have tried. If you remove those two technically undefined variables (the interpreter only knows addCustomer and insertData as properties of CustomerDB currently) from CustomerDB, insertData and addCustomer, then it will work fine:
var CustomerDB = {customers:[], addresses:[], stores:[]}
CustomerDB.insertData = function (objData){
objData.forEach(function(element){
if (element.type == "customer"){
CustomerDB.addCustomer(element.data);
};
});
};
CustomerDB.addCustomer = function (customerObj){
customerObj.add_date= new Date();
CustomerDB.customers.push(customerObj);
};
CustomerDB.insertData(allData);
console.log(CustomerDB.customers);
The alternative way using functions assigned to variables:
var insertData = function(objData) {
objData.forEach(function(element){
if (element.type == "customer"){
CustomerDB.addCustomer(element.data);
};
});
};
var addCustomer = function(customerObj) {
customerObj.add_date= new Date();
CustomerDB.customers.push(customerObj);
};
var CustomerDB = {customers:[], addresses:[], stores:[], insertData, addCustomer}
CustomerDB.insertData(allData);
console.log(CustomerDB.customers);
One final tidbit: this is ES5 syntax, and I'd strongly encourage you to explore ES6
Hope it helps
``
Rewrite your code as shown below
var CustomerDB = {customers:[], addresses:[], stores:[]}
CustomerDB.insertData = function (objData){
objData.forEach(function(element){
if (element.type == "customer"){
CustomerDB.customers.push(element.data);
};
});
};
CustomerDB.insertData(allData);
console.log(CustomerDB.customers);

How to create an object who have alias for many others object's functions

I have a situation here.
Let's show an example:
function ScrewDriver(){
var data = ...;
this.driving = function(){
//Some Stuff Here
}
}
function Hammer(){
var data = ...;
this.stomp = function(){
//Some Stuff Here
}
}
function MultiTools(){
this.screwDriver = new ScrewDriver();
this.hammer = new Hammer();
}
Here is the base of our example.
Now I would like redirect the tools functions from the multiTools but dynamicaly.
Let's explain myself:
function Work(){
this.tools = new MultiTools();
this.tools.screw(); // I want to user directly the function of the proper object
this.tools.hammer.stomp(); // Not like this;
}
I was thinking of something like that:
function MultiTools(){
this.screwDriver = new ScrewDriver();
this.hammer = new Hammer();
for(var prop in this.screwDriver){
this[prop] = this.screwDriver[prop];
}
//Same for each object
}
But it's not working like I want because if I acces to the child object data in the child object function I'll get an error.
When im calling this.tools.screw(); I want in reality this.tools.screwDriver.screw();
In finally I just want a redirection.
Someone know how to do this?
Thanks in advance.
You can use .bind():
this[prop] = this.screwDriver[prop].bind(this.screwDriver);
That ensures that when the functions are called, they'll have the correct value of this.
You could write a general function for your MultiTools object:
function MultiTools() {
var multitool = this;
function promoteMethods(subobj) {
for (var prop in subobj)
if (typeof subobj[prop] == 'function')
multitool[prop] = subobj[prop].bind(subobj);
else
multitool[prop] = subobj[prop];
}
promoteMethods(this.hammer = new Hammer());
promoteMethods(this.screwDriver = new ScrewDriver());
// ...
}

How to create a javascript library using a closure

I have written some javascript that I would to encapsulate in a closure so I can use it elsewhere. I would like do do this similar to the way jQuery has done it. I would like to be able to pass in an id to my closure and invoke some functions on it, while setting some options. Similar to this:
<script type="text/javascript">
_snr("#canvas").draw({
imageSrc : someImage.png
});
</script>
I have read a lot of different posts on how to use a closure to do this but am still struggling with the concept. Here is where I left off:
_snr = {};
(function (_snr) {
function merge(root){
for ( var i = 1; i < arguments.length; i++ )
for ( var key in arguments[i] )
root[key] = arguments[i][key];
return root;
}
_snr.draw = function (options) {
var defaults = {
canvasId : 'canvas',
imageSrc : 'images/someimage.png'
}
var options = merge(defaults, options)
return this.each(function() {
//More functions here
});
};
_snr.erase = function () {};
})(_snr);
When ever I try to call the draw function like the first code section above, I get the following error, '_snr is not a function'. Where am I going wrong here?
EDIT
Here is what I ended up doing:
function _snr(id) {
// About object is returned if there is no 'id' parameter
var about = {
Version: 0.2,
Author: "ferics2",
Created: "Summer 2011",
Updated: "3 September 2012"
};
if (id) {
if (window === this) {
return new _snr(id);
}
this.e = document.getElementById(id);
return this;
} else {
// No 'id' parameter was given, return the 'about' object
return about;
}
};
_snr.prototype = (function(){
var merge = function(root) {
for ( var i = 1; i < arguments.length; i++) {
for ( var key in arguments[i] ) {
root[key] = arguments[i][key];
}
}
return root;
};
return {
draw: function(options) {
var defaults = {
canvasId : 'canvas',
imageSrc : 'images/someimage.png'
};
options = merge(defaults, options);
return this;
},
erase: function() {
return this;
}
};
})();
I can now call:
<script type="text/javascript">
_snr("#canvas").draw({
imageSrc : someImage.png
});
</script>
Because you declared _snr as an object and not a function. Functions can have properties and methods, so there's various ways to achieve what you want, for example one of them would be say...
_snr = function(tag) {
this.tag = tag;
}
_snr.foo = function() {
//Code goes here
}
You can also pass the outer context into a closure to hide your variables from accidentally polluting the global namespace, so like...
(function(global) {
var _snr = function(tag) {
this.tag = tag;
}
_snr.foo = function() {
//Code goes here
}
//export the function to the window context:
global._snr = _snr;
})(window);
window._snr('#tag').foo('wat');
Happy coding.
Because your _snr is an object, not a function. You have to call it like this:
_snr.draw({
canvasId: '#canvas',
imageSrc: 'someImage.png'
});
When you do _snr('#canvas') that is a function call which is why you're getting that error. _snr is an object with some methods attached to it such as draw() and erase(). The reason jQuery is able to pass arguments into the $ is because they return the $ as a function object which is why we're able to pass it various selectors as arguments.
You are going wrong at the first line _snr = {}
It needs to be
_snr = function(){
selector = arguments[0]||false;
//snr init on dom object code
return _snrChild;
}
Im on a mobile phone but when im on a pc I will maybe fix the whole code c:
Here you have a snr object and that has erase and draw methods. What you intend to do is to write a _snr function which will get an id and return a wrapper object. That returned object should have erase and draw methods. so you can do
var returnedObject = _snr("my_id");
returnedObject.draw("image.png");

Categories