Обратитесь к функции javascript изнутри самого себя - программирование
Подтвердить что ты не робот

Обратитесь к функции 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

4b9b3361

Ответ 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. Остальная часть кода находится там для проверки, что она действительно работает по назначению.