This question already has answers here:
What are the differences (if any) between ES6 arrow functions and functions bound with Function.prototype.bind?
(3 answers)
Closed 7 years ago.
I'm trying to use the arrow-constructor to create an object:
var Countable = (data) => {
return data;
}
But when creating an object:
new Countable(newSubscriptions)
I get the error
Uncaught TypeError: (data) => {
return data;
} is not a constructor
I get the expected output by doing
var Countable = function(data) {
return data;
}
Yes, you can use an arrow function to create new objects:
var Countable = () => {
return {}; // This function returns a new object
};
var o = Countable();
However, you can't instantiate an arrow function, because it doesn't have the [[Construct]] internal method. So using new will throw.
Related
This question already has answers here:
Adding custom properties to a function
(10 answers)
javascript adding property to function
(2 answers)
Properties of Javascript function objects
(5 answers)
Closed 1 year ago.
I tried this:
var fun = function(){ console.log("booyah"} , {
hell: function(){
console.log("hello");
},
boy: ()=>{
alert("blah");
}
};
fun.boy();
I want that first I call fun function and then Access functions I have stored as objects. But I am getting errors . How can I fix it? Or is there any other way to do that?
Please help.
You can achieve this kind of result by editing the prototype of the function.
Example:
function foo() {
const something = 'the thing';
return something;
}
const customPrototype = {
greeting: (name) => {
const greetingTemplate = `Hello ${name}`;
return greetingTemplate;
},
randomNumber: () => {
return Math.random();
},
};
// Extending prototype to access our custom prototype functions
Object.assign(foo, customPrototype);
console.log(foo()); // the thing
console.log(foo.greeting('People')); // Hello People
console.log(foo.randomNumber()); // 0.26138311987993545
// Default prototype functions are working as well
console.log(foo.toString()); // [object Function]
EDIT: Thanks to #Bergi for correcting me!
Check the below code, reference taken from Can you create functions with custom prototypes in JavaScript?
function MyFun() {
if (!this || this==window) {
return new MyFun();
}
var f = function() {
return "thanks for calling!";
}
f.__proto__ = MyFun.prototype;
f.constructor = MyFun;
return f;
}
MyFun.prototype = {
foo: function() {
return "foo:" + this();
},
__proto__: Function.prototype
};
var f = new MyFun();
alert("proto method:"+f.foo()); // try our prototype methods
alert("function method:"+f.call()); // try standard function methods
alert("function call:"+f()); // try use as a function
alert('typeof:' + typeof f); // "function", not "object". No way around it in current js versions
alert('is MyFun:' + (f instanceof MyFun)); // true
alert('is Function:' + (f instanceof Function)); // true
This question already has answers here:
Javascript call() & apply() vs bind()?
(24 answers)
Closed 2 years ago.
let user = {
firstName: 'Testname'
}
function testAlert() {
alert(this.firstName);
}
let funcUser = testAlert.call(user); // Testname
funcUser();
Shows error in console:
Uncaught TypeError: funcUser is not a function
I am not getting why it is showing error.
Thanks
Call and apply will run your function, bind just assign context. In your example you should use bind instead of call.
instead of .call use .bind
let user = {
firstName: 'Testname'
}
function testAlert(){
alert(this.firstName);
}
let funcUser = testAlert.bind(user); // Testname
funcUser();
or you can return a function from the testAlert()
example
let user = {
firstName: 'Testname'
}
function testAlert(){
return function() { alert(this.firstName) }
}
let funcUser = testAlert.call(user); // Testname
funcUser()
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 4 years ago.
I am trying to call the same method within a method in a Javascript ES6 class but it is not working.
class Client {
constructor(connection) {
this.channels = [];
this.nickname = null;
this.user = null;
this.realName = null;
connection.on('data', this.parse_message);
}
parse_message(message) {
let messageObject = {};
if (message.includes('\r\n')) {
message = message.split('\r\n');
message.forEach((el) => {
this.parse_message(el);
});
}
else {
message = message.split(' ');
console.log('Message Received: ', JSON.stringify(message));
}
}
}
When ran I get this error TypeError: this.parse_message is not a function. I tried assigning this to a variable self at the top but that still didn't work.
Pass an arrow function as the bound handler so that you can keep this associated with the method.
connection.on('data', (...args) => this.parse_message(...args));
Now your this in the forEach callback will be the expected value.
You can use bind in the constructor:
this.parse_message = this.parse_message.bind(this);
Bind-ref:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
This question already has answers here:
Methods in ES6 objects: using arrow functions
(6 answers)
Closed 5 years ago.
I creating an object that uses async function methods with babel-polyfill/babel-preset-es2017, however I am having a problem with this:
let obj = () => {
return {
doAsync: async () => {
let thing = await longProcess()
return this.transform(thing)
},
transform: (thing) => {
return psuedoCodeTransform(thing)
}
}
}
let instance = obj()
instance.doAsync()
// TypeError: cannot read property 'transform' of undefined`.
Is this something described in ES2017, a babel-polyfill/regeneratorRuntime gotcha?
Arrow functions do not create their own context. They don't have their own this and this will refer to the enclosing scope's context. In this case (no pun intended), this does not refer to the same object as instance at all.
If you log this inside doAsync, you'll notice it's the window global.
Joseph the Dreamer's response is exactly right obviously, but since I work best by example, here is your code changed which should make it work. Notice the only change is actually defining doAsync as a normal function instead of arrow function:
let obj = () => {
return {
doAsync: async function() {
let thing = await longProcess()
return this.transform(thing)
},
transform: (thing) => {
return psuedoCodeTransform(thing)
}
}
}
let instance = obj()
instance.doAsync()
// TypeError: cannot read property 'transform' of undefined`.
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 6 years ago.
I'm using classes in ES2015 identical to the snippet below:
class ProfileManager{
constructor($http){
this._http = $http;
this.profile = {};
}
getUser(profile){
this._http(`/api/users/${user.id}`).then(function(response){
this.profile = response.data;
/*
* Results in exception because "this uses the function's
* "this" instead of the class' "this"
*/
});
}
I know I can remedy this by creating a profile variable outside of the class and using it in the class, but I was wondering if there was a cleaner or more preferred way to use class properties inside of a nested function or callback.
ES6 arrow functions do not override this
class ProfileManager {
constructor($http) {
this._http = $http;
this.profile = {};
}
getUser(profile) {
this._http(`/api/users/${user.id}`).then((response) => {
this.profile = response.data;
});
}