从本身内部引用javascript函数
考虑这段代码
var crazy = function() { console.log(this); console.log(this.isCrazy); // wrong. } crazy.isCrazy = 'totally'; crazy(); // ouput => // DOMWindow // undefined
从疯狂()里面'这个'是指这个窗口,我猜是有道理的,因为通常你会想要这个引用函数附加到的对象,但是我怎样才能让函数引用自己,并且访问一个属性本身?
回答:
不要使用arguments.callee,只是使用一个命名函数。
“注意:你应该避免使用arguments.callee()并且给每个函数(expression式)一个名字。” 通过arguments.callee上的MDN文章
我想你是在争论争论,但是现在已经废弃了。
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();
你必须给它自己的名字,所以:
var crazy = function() { console.log(crazy); console.log(crazy.isCrazy); } crazy.isCrazy = 'totally'; crazy();
这个variables只适用于一个对象的范围,例如,如果你用crazy.call(crazy)
调用你的crazy
函数的版本,它会调用crazy.call(crazy)
函数的上下文中的函数,一切都会很好。
这必须处理crazy
的function范围。 如果可以使用函数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
您可以使用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();
我怎样才能得到函数来引用自己?
“本身”的概念并不存在于function中。 你需要的是一个对象而不仅仅是一个函数。 一个对象通过关键字“this”可以获得自己的知识。 在一个函数内,“this”指向全局对象 – 在这种情况下是窗口对象。 但是如果你使用你的函数作为构造函数来创build一个对象(使用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
如果您希望在创build对象之前添加属性,则必须按如下方式将该属性添加到该函数的原型中:
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
有关代码示例的详细说明,请参阅我的博客 。
将函数绑定到自己(从@ArunPJohny和@BudgieInWA的答案中提示):
crazy = crazy.bind(crazy);
这会让你通过this
函数访问它的属性。
> crazy() function () { console.log(this); console.log(this.isCrazy); // works now }
这似乎是一个比接受的答案更好的解决scheme,它使用callee
弃用的callee
函数,并且不能在严格模式下工作。
你现在也可以用this()
recursion地调用自己的函数,如果你这么倾向的话。
我们会称之为自我提升 。 写一点实用function:
function selfthisify(fn) { return fn.bind(fn); } crazy = selfthisify(crazy); crazy();
或者,如果您更喜欢更多的“语义”名称,则可以将其accessOwnProps
。
如果你是一个语法糖types的人,你可以添加一个selfthisify
属性的函数原型:
Object.defineProperty(Function.prototype, 'selfthisify', { get: function() { return this.bind(this); } });
现在你可以说
crazy.selfthisify();
最简单的方法,使其本身可用的function是做var crazy = function crazy2() { crazy2(); }
var crazy = function crazy2() { crazy2(); }
,疯狂的和疯狂的2可以拥有相同的名字,因为第一次出现的是外部作用域中的名字,第二个是函数体中的名字。
或干脆做function crazy() { crazy(); }
function crazy() { crazy(); }
这将在两个范围内定义疯狂。
你真的想创build一个对象“类”?
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
不是指向正确types的对象,那么它将创build一个new
的对象,这将适当地确定this
范围。 其余的代码就在那里进行validation,它确实按照预期工作。