繁体   English   中英

从自身内部引用 javascript 函数

[英]Refer to javascript function from within itself

考虑这段代码

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

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

回答:

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

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

我想你是在要求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

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

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

crazy = crazy.bind(crazy);

这将使您可以通过this从函数访问其属性。

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

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

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

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

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

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

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

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

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

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

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

即如果你写,指向对象:

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's prototype
var anObject = new crazy(); //invoke the constructor

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

使函数本身在其主体中可用的最简单方法是执行var crazy = function crazy2() { crazy2(); } var crazy = function crazy2() { crazy2(); } ,没关系的疯狂和crazy2有相同的名字,因为第一次出现是在外部范围的名称,第二个是在函数体的名称。

或者干脆做function crazy() { crazy(); } function crazy() { crazy(); }将定义在这两个领域的疯狂。

为了使您的代码工作,请遵循以下

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

使用callapply方法,我们可以向函数传递一个属性,在该函数中,我们可以使用带有关键字this的属性

例如:

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

要将其与属性一起使用:

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

var name = 'Roland'

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

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

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

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

$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 其余的代码只是为了验证它确实按预期工作。

考虑这段代码

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

从crazy()内部开始,“ this”指的是窗口,我想这是有道理的,因为通常您希望此窗口引用该函数所附加的对象,但是如何获得该函数以引用其自身并进行访问本身设置的属性?

回答:

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

“注意:您应该避免使用arguments.callee(),而应为每个函数(表达式)命名。” 通过有关arguments.callee的MDN文章

暂无
暂无

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

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