If I have an object with multiple keys calling the same function and this function is implemented outside its scope, how to determine which key called this function? For example:
function tellYourAge() {
return function()
{
// I already know here that this refers to Population
// For example, console.log(this) will print the Population object
}
}
{
let Population = {
Mahdi: tellYourAge(),
Samuel: tellYourAge(),
Jon: tellYourAge()
};
Population.Mahdi(); // It should log 18
Population.Samuel(); // It should log 20
Population.Jon(); // It should log 21
}
If I have an object with multiple keys calling the same function and this function is implemented outside its scope, how to determine which key called this function? For example:
function tellYourAge() {
return function()
{
// I already know here that this refers to Population
// For example, console.log(this) will print the Population object
}
}
{
let Population = {
Mahdi: tellYourAge(),
Samuel: tellYourAge(),
Jon: tellYourAge()
};
Population.Mahdi(); // It should log 18
Population.Samuel(); // It should log 20
Population.Jon(); // It should log 21
}
Share
Improve this question
edited May 21, 2019 at 16:26
Mahdi Jaber
asked May 21, 2019 at 15:37
Mahdi JaberMahdi Jaber
2311 gold badge4 silver badges12 bronze badges
11
-
4
Pass the key as a parameter like:
Mahdi: tellYourAge('Mahdi')
– imvain2 Commented May 21, 2019 at 15:39 - 1 Those are already separate functions. – SLaks Commented May 21, 2019 at 15:41
-
8
I want to do it without passing a parameter
why? – Mosh Feu Commented May 21, 2019 at 15:42 - 4 There is no link from the key to the value. You either have to pass it or you have to rethink how it is being set up. – epascarello Commented May 21, 2019 at 15:44
- 2 You cannot achieve this exactly in the manner described. You might be able to do something either with block scoping or Function.prototype.bind. – AlexMA Commented May 21, 2019 at 15:49
4 Answers
Reset to default 9 +50It is possible
function tellYourAge() {
return function()
{
var f = arguments.callee;
var key = Object.keys(this).filter(key => this[key] === f)[0];
console.log(key);
}
}
{
let Population = {
Mahdi: tellYourAge(),
Samuel: tellYourAge(),
Jon: tellYourAge()
};
Population.Mahdi(); // prints Mahdi
Population.Samuel(); // prints Samuel
Population.Jon(); // prints Jon
}
Explanation: arguments.callee
is reference to the function to which the arguments
object belongs. And this
is basically "a thing before the dot" at the moment of function invocation, therefore your Population
object. Now what you do is lookup the called function instance in the object and you are done.
function tellYourAge() {
return function()
{
var s = new Error().stack;
if(s.includes('Mahdi')){
console.log('Age is 18');
}
else if(s.includes('Samuel')){
console.log('Age is 20');
}
else if(s.includes('Jon')){
console.log('Age is 21');
}
}
}
{
let Population = {
Mahdi: tellYourAge(),
Samuel: tellYourAge(),
Jon: tellYourAge()
};
Population.Mahdi(); // It should log 18
Population.Samuel(); // It should log 20
Population.Jon(); // It should log 21
}
Output:
Age is 18
Age is 20
Age is 21
FYI, new Error().stack will give you stacktrace like below,
Error
at Object.Samuel (<anonymous>:4:20)
at <anonymous>:1:19
I understood your question to be how can I associate a person's age with their name. The way I would do it is to create objects which describe people. Each object would have two attributes, a name and an age.
The objects (people) would then be stored in an array which is the population.
// Create a constructor function which defines a Person
function Person(name, age) {
this.name = name;
this.age = age;
}
// Create an array of Population to store the Persons (people)
var Population = [];
Population.push(new Person('Mahdi', 18));
Population.push(new Person('Samuel', 20));
Population.push(new Person('John', 21));
// Counter and limit variables
var i, l;
// Loop through the Population and display the information about the people
l = Population.length;
for (i = 0; i < l; i++) {
let person = Population[i];
console.log(person.name + " is " + person.age);
}
You haven't explained why you don't want to "pass a parameter", or what exactly the requirement to not pass a parameter is. My guess is that you want to keep the returned integer (or other value) dynamic in some sense specific to your context.
Here's how I might suggest doing it, although it's still not clear if it's a good idea:
function tellYourAge() {
return function(name)
{
let ages = {
Mahdi: 18,
Samuel: 20,
Jon: 21,
};
return ages[name];
}
}
{
let makePopulation = function(names){
let pop = {};
names.forEach(function(n){
pop[n] = tellYourAge().bind(pop, n);
});
return pop;
};
let Population = makePopulation("Mahdi", "Samuel", "Jon");
Population.Mahdi(); // It should log 18
Population.Samuel(); // It should log 20
Population.Jon(); // It should log 21
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745490174a4629953.html
评论列表(0条)