从自身内部引用 javascript 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6086008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:09:50  来源:igfitidea点击:

Refer to javascript function from within itself

javascript

提问by timoxley

Consider this piece of code

考虑这段代码

var crazy = function() {
    console.log(this);
    console.log(this.isCrazy); // wrong.
}
crazy.isCrazy = 'totally';
crazy();
// ouput =>
// DOMWindow
// undefined

From inside crazy() 'this' refers to the window, which I guess makes sense because normally you'd want this to refer to the object the function is attached to, but how can I get the function to refer to itself, and access a property set on itself?

从里面 crazy() 'this' 指的是窗口,我想这是有道理的,因为通常你希望 this 指的是函数所附加的对象,但是我怎样才能让函数引用它自己,并访问一个属性设置在自己身上?

Answer:

回答:

Don't use arguments.callee, just use a named function.

不要使用arguments.callee,只使用命名函数。

"Note: You should avoid using arguments.callee() and just give every function (expression) a name." via MDN article on arguments.callee

“注意:你应该避免使用 arguments.callee() 而只是给每个函数(表达式)一个名字。” 通过关于arguments.callee的MDN文章

采纳答案by KZ.

I think you are asking for arguments.callee, but it's deprecatednow.

我想你是在要求arguments.callee,但它现在已被弃用

https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/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

回答by zupa

As rfwsaid, this is the most straight forward way to go if the function has one single name:

正如rfw所说,如果函数只有一个名称,这是最直接的方法:

var crazy = function() {
    console.log(crazy);
    console.log(crazy.isCrazy);
};

crazy.isCrazy = 'totally';
crazy();

In case it may have different names, or you wanted to pass it around, it must be wrapped in a closure:

如果它可能有不同的名称,或者你想传递它,它必须被包裹在一个闭包中:

var crazy = (function(){
    var that = function() {
        console.log(that);
        console.log(that.isCrazy);
    };
    return that;
})();

crazy.isCrazy = 'totally';
crazy();

回答by zupa

Bind the function to itself (taking a hint from answers by @ArunPJohny and @BudgieInWA):

将函数绑定到自身(从@ArunPJohny 和@BudgieInWA 的答案中得到提示):

crazy = crazy.bind(crazy);

This will give you access from the function to its properties via this.

这将使您可以通过this.

> crazy()
function () {
    console.log(this);
    console.log(this.isCrazy); // works now
}

This seems like a better solution than the accepted answer, which uses the calleefeature which is deprecated and doesn't work in strict mode.

这似乎是比接受的答案更好的解决方案,后者使用callee已弃用且在严格模式下不起作用的功能。

You could also now have the function call itself recursively with this()were you so inclined.

如果您愿意,您现在也可以递归地调用函数本身this()

We will call this self-thisifying. Write a little utility function:

我们将称之为self-thisifying。写一个小实用函数:

function selfthisify(fn) { return fn.bind(fn); }
crazy = selfthisify(crazy);
crazy();

Or, if you prefer more "semantic" names, you could call it accessOwnProps.

或者,如果您更喜欢更多“语义”名称,则可以将其称为accessOwnProps.

If you're a syntactic sugar type of person, you could add a selfthisifyproperty to the Function prototype:

如果你是一个语法糖类型的人,你可以selfthisify向函数原型添加一个属性:

Object.defineProperty(Function.prototype, 'selfthisify', {
    get: function() { return this.bind(this); }
});

Now you can say

现在你可以说

crazy.selfthisify();

回答by zupa

You have to give it its own name, so:

你必须给它自己的名字,所以:

var crazy = function() {
    console.log(crazy);
    console.log(crazy.isCrazy);
}
crazy.isCrazy = 'totally';
crazy();

The variable thisis only applicable in the scope of an object, for instance, if you invoked your version of the crazyfunction with crazy.call(crazy), it will call the function in the context of the function crazyand all would be well.

该变量this仅适用于对象的范围,例如,如果您使用 调用您的crazy函数版本crazy.call(crazy),它将在函数的上下文中调用该函数crazy,一切都会好起来的。

回答by BudgieInWA

You can use the callmethod

您可以使用该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);

Though if your function only ever has one name, you can do this:

如果你的函数只有一个名字,你可以这样做:

var crazy = function() {
    console.log(crazy);
    console.log(crazy.isCrazy);
}
crazy.isCrazy = 'totally';
crazy();

回答by rahulmohan

how can I get the function to refer to itself?

我怎样才能让函数引用它自己?

The idea of 'itself' does not exist with functions. What you need is an object and not just a function. An object has knowledge of itself available through the keyword 'this'. Within a function, 'this' points to the global object - in this case the window object. But if you use your function as a constructor function to create an object (using the newoperator) then the object's 'this' pointer will point to the object itself.

函数中不存在“自身”的概念。你需要的是一个对象而不仅仅是一个函数。一个对象可以通过关键字“this”获得关于自身的知识。在函数中,'this' 指向全局对象——在本例中是窗口对象。但是,如果您将函数用作构造函数来创建对象(使用new运算符),则对象的“this”指针将指向对象本身。

i.e thispoints to the object if you write:

即如果你写,指向对象:

var anObject = new crazy();

So you can re-write your code as follows:

因此,您可以按如下方式重新编写代码:

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

In case you wish to add the property beforethe object is created, then you have to add the property to the function's prototypeas follows:

如果您希望创建对象之前添加属性,则必须将属性添加到函数的原型中,如下所示:

var crazy = function() {
    console.log(this);
    console.log(this.isCrazy); 
}

crazy.prototype.isCrazy = 'totally'; //add the property to the function's prototype
var anObject = new crazy(); //invoke the constructor

See more on my blogfor a detailed explanation of these concepts with code-samples.

有关这些概念的详细说明,请参阅我的博客上的更多代码示例。

回答by Adam Bergmark

Easiest way to make the function itself available in its body is to do var crazy = function crazy2() { crazy2(); }, it's okay for crazy and crazy2 to have the same name since the first occurrence is the name in the outer scope and the second is the name in the function body.

使函数本身在其主体中可用的最简单方法是 do var crazy = function crazy2() { crazy2(); }, crazy 和 crazy2 具有相同的名称是可以的,因为第一次出现是外部作用域中的名称,第二次出现是函数体中的名称。

Or simply do function crazy() { crazy(); }which will define crazy in both scopes.

或者简单地做function crazy() { crazy(); }这将在两个范围内定义疯狂。

回答by Levi Morrison

Funny that you should ask, mate. I just went through this same issue for a different purpose. The quick version of the final code is:

有趣的是你应该问,伙计。我只是为了不同的目的经历了同样的问题。最终代码的快速版本是:

$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

The critical piece:

关键部分:

    if (!(this instanceof $)) {
        return new $();
    }

If thisisn't pointing to an object of the right type, then it makes a newone, which will properly scope this. The rest of the code is just there for verification that it does indeed work as intended.

如果this不是指向正确类型的对象,那么它会生成new一个,它将正确作用域this。其余的代码只是为了验证它确实按预期工作。

回答by John Green

Are you actually trying to create an object 'class'?

您实际上是在尝试创建一个对象“类”吗?

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();