简体   繁体   English

从自身内部引用 javascript 函数

[英]Refer to javascript function from within itself

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." “注意:你应该避免使用 arguments.callee() 而只是给每个函数(表达式)一个名字。” via MDN article on arguments.callee通过关于arguments.callee的MDN文章

I think you are asking for arguments.callee, but it's deprecated now.我想你是在要求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

As rfw said, 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();

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 callee feature 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 .我们将称之为self-thisifying Write a little utility function:写一个小实用函数:

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 selfthisify property to the Function prototype:如果你是一个语法糖类型的人,你可以在函数原型中添加一个selfthisify属性:

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

Now you can say现在你可以说

crazy.selfthisify();

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 this is only applicable in the scope of an object, for instance, if you invoked your version of the crazy function with crazy.call(crazy) , it will call the function in the context of the function crazy and all would be well.变量this仅适用于对象的范围,例如,如果您使用crazy.call(crazy)调用了您版本的crazy函数,它将在函数crazy的上下文中调用该函数,一切都会好起来的.

You can use the call method您可以使用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();

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'.一个对象可以通过关键字“this”获得关于自身的知识。 Within a function, 'this' points to the global object - in this case the window object.在函数中,'this' 指向全局对象——在本例中是窗口对象。 But if you use your function as a constructor function to create an object (using the new operator) then the object's 'this' pointer will point to the object itself.但是,如果您将函数用作构造函数来创建对象(使用new运算符),则对象的“this”指针将指向对象本身。

ie this points 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 before the object is created, then you have to add the property to the function's prototype as 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 blog for a detailed explanation of these concepts with code-samples.有关这些概念的详细说明,请参阅我的博客上的更多代码示例。

Easiest way to make the function itself available in its body is to do var crazy = function crazy2() { crazy2(); }使函数本身在其主体中可用的最简单方法是执行var crazy = function crazy2() { crazy2(); } 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. var crazy = function crazy2() { crazy2(); } ,没关系的疯狂和crazy2有相同的名字,因为第一次出现是在外部范围的名称,第二个是在函数体的名称。

Or simply do function crazy() { crazy(); }或者干脆做function crazy() { crazy(); } function crazy() { crazy(); } which will define crazy in both scopes. function crazy() { crazy(); }将定义在这两个领域的疯狂。

In order to make you code to work follow below为了使您的代码工作,请遵循以下

 function crazy_object (crazy) { this.isCrazy = crazy } var create_crazy = new crazy_object('hello') //creating object console.log(create_crazy); //=> { isCrazy = 'hello' } var crazy = function() { console.log(this); //=> { isCrazy = 'totally' } console.log(this.isCrazy); //=> 'totally' } create_crazy.isCrazy = 'totally'; //=> isCrazy = 'totally' //below we pass the created object in function crazy. //And doing that we can use the keywork `this` and refer to the object crazy.call(create_crazy, null);

Using the call and apply method we can pass to a function a property,and in that function we can use the property with the keyword this使用callapply方法,我们可以向函数传递一个属性,在该函数中,我们可以使用带有关键字this的属性

For example:例如:

 function speak (message) { console.log(`A person with name ${this.name} say ${message}`); } speak.call({ name: 'Roland' }, 'Javascript is awesome');

To use it with property:要将其与属性一起使用:

function speak (message) {
  console.log(`A person with name ${this.name} say ${message}`);
}

var name = 'Roland'

speak.call({ name }, 'Javascript is awesome');

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

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 this isn't pointing to an object of the right type, then it makes a new one, which will properly scope this .如果this没有指向正确类型的对象,那么它会创建一个new的对象,该对象将正确地作用于this The rest of the code is just there for verification that it does indeed work as intended.其余的代码只是为了验证它确实按预期工作。

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”指的是窗口,我想这是有道理的,因为通常您希望此窗口引用该函数所附加的对象,但是如何获得该函数以引用其自身并进行访问本身设置的属性?

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." “注意:您应该避免使用arguments.callee(),而应为每个函数(表达式)命名。” via MDN article on arguments.callee通过有关arguments.callee的MDN文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM