I'm trying to convert es5 to es6 using lebab.
lebab es5.js -o es6.js --transform class
if I convert simple code everything is fine. For example:
var className = function(values) { this.__values = values; };
className.func = function() { return "test"; };
className.func2 = function() { return "test2"; };
className.prototype = {
_values: null,
put: function() { return 0; },
get_length: function() { return this._values.length; }
};
To
class com_cie_json_JsonArray {
constructor(values) {
this._values = values;
}
static func1() {
return "test1";
}
static func2() {
return "test2";
}
put() {
return 0;
}
get_length() {
return this._values.length;
}
}
But if I insert more fields then the Lebab either partially or not translates these pieces at all. This example not translated code.
var className = function(values) {
this.__values = values;
};
className.func = function() {
return "test";
};
className.func2 = function() {
return "test2";
};
$classes[2] = $classes["name.to.className"] = className;
className.__name__ = ["name","to","className"];
className.prototype = {
_values: null,
put: function(value) {
return 0;
},
get_length: function() {
return this._values.length;
},
__class__: className,
__properties__: {get_length:"get_length"}
};
The question is how this type of code will look in ec6. And if it’s possible how to tell the Lebab to convert it.
var className = function() {
};
$classes[2] = $classes["name.to.className"] = className;
className.__name__ = ["name","to","className"];
className.prototype = {
_values: null,
__class__: className,
__properties__: {get_length:"get_length"}
};
$classes[2] = $classes["name.to.className"] = className;
className.__name__ = ["name","to","className"];
Related
I have a static html5 and css3 website, which I want to translate. Primary language is German, and I want to translate it to English and Russian.
I found a jQuery plugin (translate.js), which does exactly what I need but I have one issue with this plugin.
Everything works perfectly, when I use for example
HTML
<p class="trn">Herzlich Willkommen</p>
jQuery:
$(function() {
var t = {
"Herzlich Willkommen": {
en: "Welcome",
ru: "Добро пожаловать"
}
};
var _t = $('body').translate({
lang: "de",
t: t
});
var str = _t.g("translate");
console.log(str);
$(".lang_selector").click(function(ev) {
var lang = $(this).attr("data-value");
_t.lang(lang);
console.log(lang);
ev.preventDefault();
});
});
but when I want to use nested trn class inside parent trn class, unfortunately I can not translate it.
For example:
<h2 class="trn">Ihr <span class="trn">Bauunternehmen</span> in <span class="trn">Wien</span></h2>
Can you help me please?
Plugin documentation
jQuery.translate.js
(function($) {
$.fn.translate = function(options) {
var that = this; //a reference to ourselves
var settings = {
css: "trn",
lang: "en"
/*,
t: {
"translate": {
pt: "tradução",
br: "tradução"
}
}
*/
};
settings = $.extend(settings, options || {});
if (settings.css.lastIndexOf(".", 0) !== 0) //doesn't start with '.'
settings.css = "." + settings.css;
var t = settings.t;
//public methods
this.lang = function(l) {
if (l) {
settings.lang = l;
this.translate(settings); //translate everything
}
return settings.lang;
};
this.get = function(index) {
var res = index;
try {
res = t[index][settings.lang];
} catch (err) {
//not found, return index
return index;
}
if (res)
return res;
else
return index;
};
this.g = this.get;
//main
this.find(settings.css).each(function(i) {
var $this = $(this);
var trn_key = $this.attr("data-trn-key");
if (!trn_key) {
trn_key = $this.html();
$this.attr("data-trn-key", trn_key); //store key for next time
}
$this.html(that.get(trn_key));
});
return this;
};
})(jQuery);
I learn how to code in javascript. I have always error: "Cannot read property 'filter' of undefined". What am I doing wrong here and why?
I have to build A class with Singleton pattern and B class which will be observer of A class.
I have to add some instances of B class to A as subscribers (observers) and unsubscribe any of it when random value I from A class is bigger than random value P from B class.
var A = (function()
{
// Instance stores a reference to the Singleton
var instance;
function init() {
// Singleton
var i = 0;
let observers = new Array();
function CheckIfGreaterThanI(observer)
{
console.log("CHECKING");
return observer.getP() > this.getI();
}
return {
subscribe: function(observer)
{
console.log("DODAJĘ");
observers.push(observer);
},
unsubscribe: function(observerss)
{
console.log("USUWAM");
for(i=0;i<observerss.length;i++)
{
var index = this.observers.indexOf(observerss[i])
if (~index)
{
this.observers.splice(index, 1);
}
}
},
notify: function()
{
for(let observer of observers)
{
observer.update();
}
},
getI: function()
{
return this.i;
},
setI: function(value)
{
this.i = value;
this.notify();
///THAT'S THE PLACE WHERE ERROR RISES
var observersToUnsubscribe = this.observers.filter(this.CheckIfGreaterThanI);
this.unsubscribe(observersToUnsubscribe);
}
};
};
return
{
// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: function () {
if ( !instance ) {
instance = init();
}
return instance;
}
};
})();
function B (name,value,a) //observer
{
this.Name = name;
this.P = value;
this.A = a;
}
B.prototype =
{
constructor:B,
getName : function()
{
return this.Name;
},
getP : function()
{
return this.P;
},
update : function()
{
if(A.getInstance().getI()<this.P)
{
console.log("OK - " + this.Name);
}
}
};
for(i=0;i<10;i++)
{
var bObject = new B(i,Math.random(),A.getInstance());
A.getInstance().subscribe(bObject);
}
var ChangeIValue = function()
{
A.getInstance().setI(Math.random());
}
setTimeout(function run()
{
ChangeIValue();
setTimeout(run,1000);
}
, 1000);
OK, I resolved this problem alone and there were many mistakes behind it, so I added my solution for that:
var A = (function()
{
// Instance stores a reference to the Singleton
var instance;
function init() {
// Singleton
var i = 0;
var observers =[];
function CheckIfGreaterThanI(observer)
{
return observer.getP() > i;
}
return {
subscribe: function(observer)
{
observers.push(observer);
},
unsubscribe: function(observersToUnsubscribe)
{
for(let observer of observersToUnsubscribe)
{
var index = observers.indexOf(observer);
if(index!=-1)
{
observers.splice(index,1);
}
}
},
notify: function()
{
for(let observer of observers)
{
observer.update();
}
},
getI: function()
{
return i;
},
setI: function(value)
{
i = value;
this.notify();
var observersToUnsubscribe = observers.filter(CheckIfGreaterThanI);
this.unsubscribe(observersToUnsubscribe);
return;
}
};
};
return {
// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: function ()
{
if ( !instance )
{
instance = init();
}
return instance;
}
};
})();
function B (name,value,a) //observer
{
this.Name = name;
this.P = value;
this.A = a;
this.getName = function()
{
return this.Name;
};
this.getP = function()
{
return this.P;
};
this.update = function()
{
if(A.getInstance().getI()<this.P)
{
console.log("OK - " + this.Name);
}
};
};
for(j=0;j<10;j++)
{
var bObject = new B(j,Math.random(),A.getInstance());
A.getInstance().subscribe(bObject);
}
var ChangeIValue = function()
{
A.getInstance().setI(Math.random());
}
setTimeout(function run()
{
ChangeIValue();
setTimeout(run,1000);
}
, 1000);
How can i send parameter this to function.
Above options work in constructor :
selectors[i].onblur = this.validation;
But if in function Valid i call the selectors[i].validation, above solution will not working. Does Somebody know, how to call selectors[i].validation with parameter this??
For any help, i will be very grateful.
link to demo:
http://codepen.io/anon/pen/YqryVr
My js classes:
var Validator = (function () {
var errorClassName = "error";
var selectors;
var regexMap;
function Validator(id, regexObject) {
if (id === void 0) { id = "form"; }
regexMap = regexObject.getMap();
selectors = document.getElementById(id).elements;
for (i = 0; i < selectors.length; ++i) {
selectors[i].onblur = this.validation;
}
};
Validator.prototype.setErrorClassName = function (className) {
errorClassName = className;
};
Validator.prototype.addClass = function (selector) {
if(selector.className.indexOf(errorClassName) < 1)
selector.className += " " + errorClassName;
};
Validator.prototype.removeClass = function (selector) {
selector.className = selector.className.replace(errorClassName, '');
};
Validator.prototype.validation = function () {
alert('this.type: ' + this.type);
switch(this.type) {
case 'textarea':
case 'text':
if(this.dataset.regex in regexMap) this.dataset.regex = regexMap[this.dataset.regex];
var pattern = new RegExp(this.dataset.regex);
if(this.value.length !== 0 && pattern.test(this.value)) {
Validator.prototype.removeClass(this);
return true;
} else {
Validator.prototype.addClass(this);
return false;
}
break;
case 'select-one':
if(this.value.length === 0) {
Validator.prototype.addClass(this);
return false;
} else {
Validator.prototype.removeClass(this);
return true;
}
break;
}
return true;
};
Validator.prototype.valid = function () {
for (i = 0; i < selectors.length; ++i) {
selectors[i].validation;
}
return true;
};
return Validator;
}());
var SelectorAttribute = (function () {
function SelectorAttribute(name, regex) {
this.name = name;
this.regex = regex;
}
SelectorAttribute.prototype.toString = function () {
return "name: " + this.name + ", regex = " + this.regex;
};
return SelectorAttribute;
}());
var StandardRegexPatterns = (function () {
var map = {};
function StandardRegexPatterns() {
map['zip-code-poland'] = '^[0-9]{2}-[0-9]{3}$';
map['phone-number-poland'] = '^[0-9]{9}$';
map['digits'] = '^[0-9]+$';
map['alpha'] = '^[a-zA-z]+$';
map['email'] = '^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*#([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?';
map['login'] = '^[a-z0-9_-\.]{3,21}$';
map['ip-address'] = '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$';
map['url-address'] = '^((http[s]?|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+[^#?\s]+)(.*)?(#[\w\-]+)?$';
}
StandardRegexPatterns.prototype.getMap = function () {
return map;
};
return StandardRegexPatterns;
}());
$( document ).ready(function() {
var validator = new Validator('form', new StandardRegexPatterns());
validator.setErrorClassName("error");
//var pattern = new StandardRegexPatterns();
// alert(Object.keys(pattern.getMap()));
$("button").on('click', function(){
alert(validator.valid());
});
});
You can use the following:
functionname.apply(this, [arguments]);
or
functionname.call(this, argument1, argument2);
if you don't have arguments you can just omit them.
I usually just do this:
funcitonname.apply(this, Arguments);
if I'm calling this method from within a function already so I can carry on the arguments to the functionname().
Learn more about apply
Learn more about call
I have a sealed object with an array member on which I want to prevent direct pushes.
var myModule = (function () {
"use strict";
var a = (function () {
var _b = {},
_c = _c = "",
_d = [];
Object.defineProperty(_b, "c", {
get: function () { return _c; }
});
Object.defineProperty(_b, "d", {
get { return _d; }
});
_b.addD = function (newD) {
_d.push(newD);
};
Object.seal(_b);
return _b;
}());
var _something = { B: _b };
return {
Something: _something,
AddD: _b.addD
};
}());
myModule.Something.c = "blah"; // doesn't update = WIN!!
myModule.AddD({}); // pushed = WIN!
myModule.Something.d.push({}); // pushed = sadness
How can I prevent the push?
UPDATE:
Thanks for all the thoughts. I eventually need the JSON to send to the server. It looks like I might need to use an object for the array then figure out a way to generate and return the JSON needed, or change _something to use .slice(). Will play and report.
you could override the push method:
var _d = [];
_d.__proto__.push = function() { return this.length; }
and when you need to use it in your module, call Array.prototype.push:
_b.addD = function (newD) {
Array.prototype.push.call(_d, newD);
};
I haven't done any performance tests on this, but this certainly helps to protect your array.
(function(undefined) {
var protectedArrays = [];
protectArray = function protectArray(arr) {
protectedArrays.push(arr);
return getPrivateUpdater(arr);
}
var isProtected = function(arr) {
return protectedArrays.indexOf(arr)>-1;
}
var getPrivateUpdater = function(arr) {
var ret = {};
Object.keys(funcBackups).forEach(function(funcName) {
ret[funcName] = funcBackups[funcName].bind(arr);
});
return ret;
}
var returnsNewArray = ['Array.prototype.splice'];
var returnsOriginalArray = ['Array.prototype.fill','Array.prototype.reverse','Array.prototype.copyWithin','Array.prototype.sort'];
var returnsLength = ['Array.prototype.push','Array.prototype.unshift'];
var returnsValue = ['Array.prototype.shift','Array.prototype.pop'];
var funcBackups = {};
overwriteFuncs(returnsNewArray, function() { return []; });
overwriteFuncs(returnsOriginalArray, function() { return this; });
overwriteFuncs(returnsLength, function() { return this.length; });
overwriteFuncs(returnsValue, function() { return undefined; });
function overwriteFuncs(funcs, ret) {
for(var i=0,c=funcs.length;i<c;i++)
{
var func = funcs[i];
var funcParts = func.split('.');
var obj = window;
for(var j=0,l=funcParts.length;j<l;j++)
{
(function() {
var part = funcParts[j];
if(j!=l-1) obj = obj[part];
else if(typeof obj[part] === "function")
{
var funcBk = obj[part];
funcBackups[funcBk.name] = funcBk;
obj[part] = renameFunction(funcBk.name, function() {
if(isProtected(this)) return ret.apply(this, arguments);
else return funcBk.apply(this,arguments);
});
}
})();
}
}
}
function renameFunction(name, fn) {
return (new Function("return function (call) { return function " + name +
" () { return call(this, arguments) }; };")())(Function.apply.bind(fn));
};
})();
You would use it like so:
var myArr = [];
var myArrInterface = protectArray(myArr);
myArr.push(5); //Doesn't work, but returns length as expected
myArrInterface.push(5); //Works as normal
This way, you can internally keep a copy of the interface that isn't made global to allow your helper funcs to modify the array as normal, but any attempt to use .push .splice etc will fail, either directly, or using the .bind(myArr,arg) method.
It's still not completely watertight, but a pretty good protector. You could potentially use the Object.defineProperty method to generate protected properties for the first 900 indexes, but I'm not sure of the implications of this. There is also the method Object.preventExtensions() but I'm unaware of a way to undo this effect when you need to change it yourself
Thank you, dandavis!
I used the slice method:
var myModule = (function () {
"use strict";
var a = (function () {
var _b = {},
_c = _c = "",
_d = [];
Object.defineProperty(_b, "c", {
get: function () { return _c; }
});
Object.defineProperty(_b, "d", {
get { return _d.slice(); } // UPDATED
});
_b.updateC = function (newValue) {
_c = newValue;
};
_b.addD = function (newD) {
_d.push(newD);
};
Object.seal(_b);
return _b;
}());
var _something = { B: _b };
return {
Something: _something,
AddD: _b.addD
};
}());
myModule.Something.c = "blah"; // doesn't update = WIN!!
myModule.AddD({}); // pushed = WIN!
myModule.Something.d.push({}); // no more update = happiness
This allows me to protect from direct push calls enforcing some logic.
I want to be able to assign default values to variables when I'm using prototyping for object creation.
When I try to assign default values to the variables they are always 'undefined'.
I have tried to find the answer but all the possible solutions I have tried dont work.
My questions are:
why do a variable that have I have initiated with a value has the value 'undefined'
how do I solve my problem?
(function() {
EmployeeNS = {};
EmployeeNS.Employee = function() {
var _firstName;
var _lastName;
var _employeeID = 'Unassigned';
}
EmployeeNS.Employee.prototype.setFirstName = function(fName) { this._firstName = fName; };
EmployeeNS.Employee.prototype.getFirstName = function() { return this._firstName; };
EmployeeNS.Employee.prototype.setLastName = function(lName) { this._lastName = lName; };
EmployeeNS.Employee.prototype.getLastName = function() { return this._lastName; };
EmployeeNS.Employee.prototype.setEmployeeID = function(employeeID) { this._employeeID = employeeID; };
EmployeeNS.Employee.prototype.getEmployeeID = function() { return this._employeeID; };
EmployeeNS.Worker = function() {
var _department;
}
EmployeeNS.Worker.prototype = new EmployeeNS.Employee();
EmployeeNS.Worker.prototype.constructor = Worker;
EmployeeNS.Worker.prototype.setDepartment = function(department) { this._department = department; };
EmployeeNS.Worker.prototype.getDepartment = function() { return this._department; };
})();
function createWorker() {
var x = new EmployeeNS.Worker();
x.setFirstName("John");
x.setLastName("Doe");
x.setDepartment("Transport");
var message = x.getFirstName()
+ " "
+ x.getLastName()
+ " (Department: "
+ x.getDepartment()
+ " / EmployeeID: "
+ x.getEmployeeID()
+ ")";
alert(message);
}
Thanks
you can simply make it to work by changing like this,
EmployeeNS.Employee = function() {
this._firstName;
this._lastName;
this._employeeID = 'Unassigned';
}
Try out this way , you can make those variables truly private by wrapping Employee ,
(function() {
EmployeeNS = {};
(function() {
var _firstName;
var _lastName;
var _employeeID = 'Unassigned';
EmployeeNS.Employee = function() {
}
EmployeeNS.Employee.prototype.setFirstName = function(fName) { _firstName = fName; };
EmployeeNS.Employee.prototype.getFirstName = function() { return _firstName; };
EmployeeNS.Employee.prototype.setLastName = function(lName) { _lastName = lName; };
EmployeeNS.Employee.prototype.getLastName = function() { return _lastName; };
EmployeeNS.Employee.prototype.setEmployeeID = function(employeeID) { _employeeID = employeeID; };
EmployeeNS.Employee.prototype.getEmployeeID = function() { return _employeeID; };
})();
(function() {
var _department;
EmployeeNS.Worker = function() {
}
EmployeeNS.Worker.prototype = new EmployeeNS.Employee();
EmployeeNS.Worker.prototype.constructor = Worker;
EmployeeNS.Worker.prototype.setDepartment = function(department) { _department = department; };
EmployeeNS.Worker.prototype.getDepartment = function() { return _department; };
})();
})();
Here is the jsfiddle
If you want instance properties, do it like this:
(function() {
EmployeeNS = {};
EmployeeNS.Employee = function () {
this._firstName = null;
this._lastName = null;
this._employeeID = 'Unassigned';
};
EmployeeNS.Employee.prototype.setFirstName = function(fName) {
this._firstName = fName;
};
})();