Хочу узнать из функции которую вызвали, кто именно её вызвал, и чтобы можно было обращаться к этой функции и к её prototype.
let useState = val => {
// как узнать здесь кто вызвал функцию?
}
function test(){
useState(123)
}
такие методы как Function.caller не подходят, ибо очень старые. Как можно по новому узнать кто вызвал функцию.
Насколько я понимаю, надёжного способа нет.
Function.caller
не рекомендовано к использованию.
Можно попробовать распарсить стек, но это тоже будет хрупкий костыль на костыле:
let useState = val => {
const callerName = new Error().stack.split('\n')[2].split(/\s+/)[2];
console.log(eval(callerName).prototype);
}
function test() {
useState(123);
}
test.prototype.foo = 42;
test(); // { foo: 42 }
Так что вам лучше предусмотреть в вашем API какой-то явный способ передавать информацию о контексте вызова.
Можно, например, распарсив (new Error).stack
.
function getStack(сколькоПропустить = 1){
const регуляркаАнонима = /^at (\S+) \(<anonymous>\)$/,
регуляркаФункции = /^at (\S+) \(([^:]+):([^:]+):(\d+):(\d+)\)$/,
регуляркаФайла = /^at ([^:]+):([^:]+):(\d+):(\d+)$/;
return (new Error).stack
.split(/\n/g)
.filter((строка,номер) => номер > сколькоПропустить)
.map(строка => строка.trim())
.map(строка => регуляркаАнонима.exec(строка)||
регуляркаФункции.exec(строка)||
регуляркаФайла.exec(строка))
.map(результат =>
результат.length < 3 ?
{ функция: результат[1] } :
результат.length > 5 ?
{ функция: результат[1],
файл: `${результат[2]}:${результат[3]}`,
строка: результат[4],
символ: результат[5]} :
{ файл: `${результат[1]}:${результат[2]}`,
строка: результат[3],
символ: результат[4]}
);
}
const prototypeflag = Symbol('true');
iAmCallingThatFunction.prototype = {
[prototypeflag]: true
};
function whoCallsMe(){
const стэк = getStack(2);
console.log('стэк', стэк);
const функция = findFunctionWithNeededPrototype(стэк);
console.log('функция', функция);
const прототип = функция.prototype;
console.log('нужный прототип?',прототип[prototypeflag]);
}
function iAmCallingThatFunction(){
whoCallsMe();
}
iAmCallingThatFunction();
var Массив = class extends Array {
get [prototypeflag](){ return !0; }
methodThatCallsFunction(){
this.forEach(function() {
whoCallsMe();
});
this.forEach(whoCallsMe);
}
}
const массив = new Массив(1).fill(0);
массив.methodThatCallsFunction();
function findFunctionWithNeededPrototype(стэк){
for(let индекс = 0; индекс < стэк.length; индекс++){
let имя = стэк[индекс].функция;
if(!имя) continue;
if(/\./.test(имя))
имя = имя.replace(/\..*$/,'');
if(имя && 'function' == typeof window[имя] &&
window[имя].prototype[prototypeflag])
return window[имя];
}
throw new Error('Неправильная функция');
}
К примеру клиент обратился ко мне и просит чтобы я добавил для его сайта некоей функциональности или что-то другое не важно, как именно происходит...
Помогите пожалуйста с регулярными выражениямиЕсть строка