[Vuejs]-Return Function or Object Javascript

0👍

No, you can’t – what you have in that array is a function reference, which means you can only do this:

mixins[0]()

To call your function. If you want the return value of the function to be stored in the array, you’d need to do what you were already doing:

mixins: [
  pageMixin()
]

-1👍

I am not a Javascript expert, but I have cobbled together what I believe is a solution. It is based off of this SO question.

I will reduce your question to the following: “I have a function f. I would like an object o so that o behaves like f(), but o(a, b, c, ...) behaves like f(a, b, c, ...)

Say, for example, we have a function for creating “people”:

function makePerson(firstname, age) {
  firstname = firstname || "Jackson";
  age = age || 17;
  return { firstname: firstname, age: age };
}

and we’d like makePerson to act like makePerson(). I will consider it sufficient to have that makePerson.firstname == "Jackson" and makePerson.age == 17. That is, we care about making all the attributes correct.

We can do this by setting the prototype of makePerson to a new function object which has the attributes that we desire:

// Create a function object
const functionObject = Object.create(Function.prototype);
// Get the default value
const defaultValue = makePerson();
// Copy all the attributes from the default value to the function object
Object.assign(functionObject, defaultValue);
// Make the function object the prototype of our function
Object.setPrototypeOf(makePerson, functionObject);

and see that this works:

console.log(makePerson.firstname); // Jackson
console.log(makePerson.age); // 17

// Still works as a function
console.log(makePerson()); // { name: 'Jackson', age: 17 }
console.log(makePerson("Oliver", 50)); // { name: 'Oliver', age: 50 }

If you want, you could wrap this all up in a function:

function emulateDefault(func) {
  /* Return a function `newFunc` such that `newFunc` behaves like
     `func()` and `newFunc(...args)` behaves like `func(...args)`. */

  // Clone `func`
  const funcClone = Object.create(Function.prototype);
  Object.assign(funcClone, func);

  // Create a function object
  const functionObject = Object.create(Function.prototype);
  // Get the default value
  const defaultValue = func();
  // Copy all the attributes from the default value to the function object
  Object.assign(functionObject, defaultValue);
  // Make the function object the prototype of our function
  Object.setPrototypeOf(funcClone, functionObject);

  return funcClone;
}

and then you could write pageMixin like:

const pageMixin = emulateDefault(function() { ... });

I want to note that I am not 100% positive about everything that is going on here, and there may be edge cases that I have not accounted for. In particular, Javascript cloning is particularly difficult, so emulateDefault may have issues due to that, and I don’t know the details of Object.new, Object.setPrototypeOf, or Object.assign.

Leave a comment