I need to make some js functionality like that:
let text =function()
{
this.main = ...;
this.toArr = ...;
};
let t = new text();
console.log( t() ); // call a function 'main' in text;
t().toArr(); // call a function 'toArr' in text;
Try this:
let text = function (myarg) {
// Usage: var t = new text(<arg>);
this.uniqueProperty = "test";
var main = () => {
// main code
return {
toArr: () => {
return [myarg, this.uniqueProperty];
}
};
};
return main;
}
var t = new text("hey world");
console.log(t());
console.log(t().toArr());
Calls are the same as in your question
Note: your main function returns object now.
How does this work?
You call new text("arg"), but constructor returns main function instead of this. Main function returns object with toArr function, and can be accessed through new text("arg")().toArr code. Why I put both functions into () => {}?. The answer is simple - that's how to access text instance properties. So we can access unique text properties. Else, this will be main function reference.
Please take a deeply look at MDN's Inheritance part.
This is a simple usage as below:
let text = function()
{
this.main = function(){
return {a:1};
}
this.toArr = function(){
return [1,2,3];
}
};
let t = new text();
console.log( t.main() ); // call a function 'main' in text;
console.log(t.toArr()); // call a function 'toArr' in text;
Related
My example code:
var Person = (function () {
var __sym = Symbol('Person');
class Person {
constructor(name) {
this[__sym] = { name: name };
}
getName() {
let _this = this[__sym];
return _this.name;
}
}
return Person;
}());
var person = new Person('Hermione');
console.log(person.name); // undefined
console.log(person.getName()); // Hermione
In this example, I'd use __sym as a key to assign to the private data.
My question is: How to bind this[__sym] to every method inside the Person class?
My real project:
let Chatwindow = (function () {
let __sym = Symbol('Chatwindow');
let __data = {};
// for typo
let __prop = {
targetUserId: 'targetUserId'
};
__data.init = function (...args) {
let _this = this[__sym];
let options = args[0];
// validating the type of 'options' and the properties...
// just get what I need
_this[__prop.targetUserId] = options[__prop.targetUserId];
(async () => {
let messages = await __data.getMessagesAsync.call(_this);
// my goal:
// let messages = await __data.getMessagesAsync();
})();
};
__data.getMessagesAsync = function () {
let _this = this;
let promise = new Promise(function (done) {
// create model before sending
let model = { [__prop.targetUserId]: _this[__prop.targetUserId] };
// sending...
done();
});
return promise;
};
class Chatwindow {
constructor() {
this[__sym] = {};
}
set init(value) {
return __data.init;
}
get init() {
return (...args) => __data.init.call(this, ...args);
}
}
return Chatwindow;
}());
Everytime I call a method, I have to use call(_this) function to bind the key, like this:
let messages = await __data.getMessagesAsync.call(_this);
After that, inside the getMessagesAsync method, I can assign to the private data using this property.
What I want to achieve: I want to bind all of the methods just one time inside the init method. How can I do that?
Something like this:
__data.getMessagesAsync.oncall = function () {
// bind this with this[__sym]
};
Then,
__data.getMessagesAsync(); // no need to pass anymore
Thank you!
You can use arrow functions, so you will be sure that context (this) will be same every time (this will be pointing to parent this no matter from where arrow function is called)
__data.getMessagesAsync = () => {
let promise = new Promise((done) => {
// create model before sending
let model = { [__prop.targetUserId]: this[__prop.targetUserId] };
// sending...
done();
});
return promise;
}
In javascript, using function_name.bind(o) allows you to create a new function whose context this is bound to the object o.
What you want is to create a new function:
__data.boundMessagesFunction = __data.getMessagesAsync.bind(_this);
Now you can call:
let messages = await __data.boundMessagesFunction();
I am having trouble accessing fields(variables) in a function definition. My question is with this code:
<script>
function test(){ var book= [];}
var arrs = test();
alert(arrs.book);
</script>
It gives me 'undefined', why? I would expect it to be an empty value. Is there any way I can access this book array variable in arrs?
arrs is undefined because test() doesn't return anything. All the function does is locally declare a variable and then end, so the local variable just falls out of scope and nothing happens.
Based on the usage, it looks like you want your function to maybe return an object?:
function test() {
return { book: [] };
}
Or maybe the function should itself construct an object and you meant to call it with new?:
function test() {
this.book = [];
}
var arrs = new test();
Like Carcigenicate said, you are missing the return statement inside test().
function test(){
var book= [];
// missing return...
return book;
}
var arrs = test();
alert(arrs);
Try it now.
// old way
function Test1() {
this.books = ['t1']
}
var t1 = new Test1()
alert(t1.books)
//es6 class
class T2 {
constructor() {
this.books = ['t2']
}
}
var t2 = new T2()
alert(t2.books)
// plain object
var t3 = {
books: ['t3']
}
alert(t3.books)
// static field
function T4() {}
T4.prototype.books = []
var t4a = new T4(),
t4b = new T4()
t4a.books.push('t4')
alert(t4b.books)
i try to understand javascript now
what i really want to achieve is something like this :
var data = Data.GetData();//with or without parameter Data.GetData(x)
//or
var data = Data.Row.GetData();
what i understand from other oop languange i just create class like this :
Class Data{
public static String GetData()
{
return "data";
}
}
So I can call :
String data = Data.GetData();
//or
Data _data = new Data();
String x = _data.GetData();
but how in javascript?
i think like this :
function Data(){
function GetData(){
retun "data";
}
}
but it didn't work. :(
please help me understand oop how to make this in javascript, with example code :D
In javascript you can declare a function as a constructor (by making sure it doesn't return anything) and then have methods for that class applied to all its instances by using prototypal inheritance.
function Data () {
}
Data.prototype.GetData = function () {
return 'data';
}
you can then use it like so:
var data = new Data();
var str = data.GetData();
if you want a static method you can omit the prototype keyword
Data.GetData = function () { return 'data'; }
If instead your Data object is a single object and you don't want to reuse any of its methods and members you can simply declare it like this:
var Data = {
GetData: function () { return 'data'; }
};
and then do
Data.GetData();
Data is a simple Object, and GetData is a key with function as value
var Data = {
GetData: function() {
return "data";
}
}
in the second case:
var Data = {
Row: {
GetData: function() {
return "data";
}
}
}
Functions in JavaScript are first class objects. "Methods" are just properties on objects that point to functions. The act of calling the function via a property reference is a bit special, in that it sets the meaning of this within the call to the function (this is set to the object the property was on). Unlike some other languages you may be used to, that is a runtime thing decided by how the function is called, not a compile-time thing decided by where the function is declared/defined.
To be able to do this:
var data = Data.GetData();
...you need to have an object, Data, that has a property called GetData that refers to a function. You can build that like this:
var Data = {
GetData: function() {
// ...your code here...
}
};
...or any of several other ways, such as:
var Data = {};
Data.GetData = function() {
// ...your code here...
};
...or
var Data = {};
Data.GetData = GetData;
function GetData() {
// ...your code here...
}
More on my blog: Mythical methods
Try it like this:
function Data() {
this.getData = function() {
return "data";
};
this.ROW = {
getData : function() {
return "Row Data";
}
}
}
You the call the function from a new instance of Data:
new Data().getData();
OR
new Data().ROW.getData();
This will return the data.
I have a Constructor like below
var Example = (function () {
function Example(opt) {
this.opt = opt;
return{
function(){ console.log(this.check()); } // Here is an Error
}
}
Example.prototype.check = function () {
console.infor('123');
};
return Example;
}) ();
var ex = new Example({ a:1 });
I know that I am doing wrong but unable to figure out the way to do this. I want to use prototype method inside the object return. Please help me on this.
If you wanted to run check() when building an instance, why not call it in the constructor?
var Example = (function () {
function Example(opt) {
this.opt = opt;
this.check(); //this gets called when instances are made
}
Example.prototype.check = function () {
console.infor('123');
};
return Example;
}) ();
//so `ex` is an instance of the Example Constructor
//and check gets called when you build it
var ex = new Example({ a:1 });
Look at
function Example(opt) {
this.opt = opt;
this.check()
}
Example.prototype.check = function () {
console.info('123');
};
Ok this may be a noobolicious question as im new to OOP.
Im attempting to build something of a JS Object Library and was wondering if I could do it using nested functions??
var object = new function() {
this.action1 = function () {
this.dostuff1 = function () {
return "dostuff1";
};
this.dostuff2 = function () {
return "dostuff2";
};
};
I am having trouble accessing the third level functions. Can I nest like this?
this.action2 = function () {
return "action2";
};
alert(object.action1.dostuff2());
While Eberlin's answer is perfectly correct I'd suggest you to create a nested object which in turn again exposes functions rather than nesting functions itself. Otherwise this might become a maintainability nightmare.
Basically you could create
var Child = function(){
//constructor
};
Child.prototype.doStuff2 = function(){
return "dostuff2";
};
var Root = function(obj){
//constructor
this.child = obj;
};
Root.prototype.action1 = function(){
return "doStuff1";
};
//usage
var myRoot = new Root(new Child());
myRoot.action1();
myRoot.child.action2();
Here's a live example: http://jsbin.com/ijotup/edit#javascript,live
See below for some code cleanup:
var o = (new function () { // changed 'object' to 'o'
this.action1 = (function () { // added parentheses, not required.
this.dostuff1 = (function () { // does not return anything.
return "dostuff1"; // and is also not the proper way to organize
}); // ** look at the javascript prototype
return this; // now it does
}); // missing closing bracket
this.dostuff2 = (function () {
return "dostuff2";
});
});
alert(o.action1().dostuff2()); // action1 is a function, not a variable.
Hope this helps. Also, here's a brief tutorial on the javascript prototype.