Обратитесь к функции javascript изнутри самого себя
Рассмотрим этот фрагмент кода
var crazy = function() {
console.log(this);
console.log(this.isCrazy); // wrong.
}
crazy.isCrazy = 'totally';
crazy();
// ouput =>
// DOMWindow
// undefined
Изнутри crazy() 'this' относится к окну, которое, я думаю, имеет смысл, потому что обычно вам нужно, чтобы это ссылалось на объект, к которому привязана функция, но как я могу заставить функцию ссылаться на себя, и получить доступ к набору свойств по себе?
Ответ:
Не используйте arguments.callee, просто используйте именованную функцию.
"Примечание. Вам следует избегать использования arguments.callee() и просто дать каждой функции (выражение) имя." через статья MDN на arguments.callee
Ответы
Ответ 1
Я думаю, что вы запрашиваете аргументы. callee, но теперь он устарел.
https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee
var crazy = function() {
console.log(this);
console.log(arguments.callee.isCrazy); // right.
}
crazy.isCrazy = 'totally';
crazy();
// ouput =>
// DOMWindow
// totally
Ответ 2
Как сказал rfw, это самый прямой путь, если функция имеет одно имя:
var crazy = function() {
console.log(crazy);
console.log(crazy.isCrazy);
};
crazy.isCrazy = 'totally';
crazy();
Если у него могут быть разные имена или вы хотите передать их, он должен быть завернут в закрытие:
var crazy = (function(){
var that = function() {
console.log(that);
console.log(that.isCrazy);
};
return that;
})();
crazy.isCrazy = 'totally';
crazy();
Ответ 3
Вы должны дать ему свое имя, поэтому:
var crazy = function() {
console.log(crazy);
console.log(crazy.isCrazy);
}
crazy.isCrazy = 'totally';
crazy();
Переменная this
применима только в области объекта, например, если вы вызывали вашу версию функции crazy
с помощью crazy.call(crazy)
, она вызывается функцией в контексте функции crazy
и все будет хорошо.
Ответ 4
Это должно иметь дело с объемом функции crazy
. Если можно передать любую область функции, используя функцию call()
.
Вместо
crazy();
Использование
crazy.call(crazy);
Подробнее см.
http://odetocode.com/blogs/scott/archive/2007/07/05/function-apply-and-function-call-in-javascript.aspx
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Call
http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
Ответ 5
Вы можете использовать метод call
var crazy = function() {
console.log(this);
console.log(this.isCrazy);
}
crazy.isCrazy = 'totally';
crazy.call(crazy);
// calls crazy using crazy as the target, instead of window:
// functionToCall.call(objectToUseForThis);
Хотя если ваша функция имеет только одно имя, вы можете сделать это:
var crazy = function() {
console.log(crazy);
console.log(crazy.isCrazy);
}
crazy.isCrazy = 'totally';
crazy();
Ответ 6
как я могу заставить функцию ссылаться на сам?
Идея "самого себя" не существует с функциями. Вам нужен объект, а не только функция. Объект обладает знаниями о себе через ключевое слово 'this'. Внутри функции 'this' указывает на глобальный объект - в этом случае объект окна. Но если вы используете функцию в качестве функции-конструктора для создания объекта (используя новый оператор), то указатель объекта 'this' укажет на сам объект.
i.e это указывает на объект, если вы пишете:
var anObject = new crazy();
Итак, вы можете переписать свой код следующим образом:
var crazy = function() {
this.printMe = function(){
console.log(this);
console.log(this.isCrazy);
}
}
var anObject = new crazy(); //create an object
anObject.isCrazy = 'totally'; //add a new property to the object
anObject.printMe(); //now print
Если вы хотите добавить свойство до создания объекта, вам необходимо добавить свойство в прототип функции следующим образом:
var crazy = function() {
console.log(this);
console.log(this.isCrazy);
}
crazy.prototype.isCrazy = 'totally'; //add the property to the function prototype
var anObject = new crazy(); //invoke the constructor
Подробнее о моем блоге для подробного объяснения этих понятий с помощью кодовых образцов.
Ответ 7
Привяжите функцию к себе (беря подсказку из ответов @ArunPJohny и @BudgieInWA):
crazy = crazy.bind(crazy);
Это даст вам доступ от функции к ее свойствам через this
.
> crazy()
function () {
console.log(this);
console.log(this.isCrazy); // works now
}
Это похоже на лучшее решение, чем принятый ответ, который использует функцию callee
, которая устарела и не работает в строгом режиме.
Вы также можете теперь вызвать вызов функции рекурсивно с помощью this()
, если бы вы были так склонны.
Мы будем называть это самоопределяющимся. Напишите небольшую полезную функцию:
function selfthisify(fn) { return fn.bind(fn); }
crazy = selfthisify(crazy);
crazy();
Или, если вы предпочитаете больше "семантических" имен, вы можете назвать его accessOwnProps
.
Если вы являетесь синтаксическим типом типа сахара, вы можете добавить свойство selfthisify
в прототип функции:
Object.defineProperty(Function.prototype, 'selfthisify', {
get: function() { return this.bind(this); }
});
Теперь вы можете сказать
crazy.selfthisify();
Ответ 8
Самый простой способ сделать функцию самой доступной в своем теле - это сделать
var crazy = function crazy2() { crazy2(); }
, это нормально для сумасшедшего и сумасшедшего2 с тем же именем, поскольку первое вхождение - это имя во внешней области, а второе - это имя в теле функции.
Или просто function crazy() { crazy(); }
, который определит сумасшествие в обеих областях.
Ответ 9
Вы действительно пытаетесь создать объект "класс"?
function crazy(crazyState) {
this.isCrazy = crazyState;
console.log(this);
console.log(this.isCrazy);
}
crazy.prototype.alertMe = function() { alert('I am '+ this.isCrazy +' crazy.'); }
var crazyObj = new crazy('totally');
crazyObj.alertMe();
crazyObj.isCrazy = 'not';
crazyObj.alertMe();
Ответ 10
Забавно, что вы должны спросить, приятель. Я просто прошел эту же проблему для другой цели. Быстрая версия окончательного кода:
$a = function() {};
$ = function() {
if (!(this instanceof $)) {
return new $();
}
this.name = "levi";
return this;
};
//helper function
var log = function(message) {
document.write((message ? message : '') + "<br/>");
};
log("$().name == window.name: " + ($().name == window.name)); //false
log("$().name: " + $().name); //levi
log("window.name: " + window.name); //result
log();
log("$a instanceof $: " + ($a instanceof $)); //false
log("typeof $a: " + (typeof $a)); //function
log("typeof $: " + (typeof $)); //function
Критическая часть:
if (!(this instanceof $)) {
return new $();
}
Если this
не указывает на объект правильного типа, то он делает new
один, который будет правильно обладать this
. Остальная часть кода находится там для проверки, что она действительно работает по назначению.