簡體   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