考虑这段代码
var crazy = function() {
console.log(this);
console.log(this.isCrazy); // wrong.
}
crazy.isCrazy = 'totally';
crazy();
// ouput =>
// DOMWindow
// undefined
从内部疯狂()'这个'指的是窗口,我觉得这很有意义,因为通常你想要这个引用函数附加的对象,但是我怎样才能让函数引用它自己,并访问自己设置的属性?
答案:
不要使用arguments.callee,只需使用命名函数。
“注意:你应该避免使用arguments.callee(),只需给每个函数(表达式)一个名字。”通过MDN article on arguments.callee
答案 0 :(得分:26)
我认为你要求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
答案 1 :(得分:14)
正如 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();
答案 2 :(得分:4)
你必须给它自己的名字,所以:
var crazy = function() {
console.log(crazy);
console.log(crazy.isCrazy);
}
crazy.isCrazy = 'totally';
crazy();
变量this
仅适用于对象的范围,例如,如果您使用crazy
调用crazy.call(crazy)
函数的版本,它将调用该函数函数crazy
的上下文,一切都会很好。
答案 3 :(得分:4)
将函数绑定到自身(从@ArunPJohny和@BudgieInWA的答案中得到提示):
crazy = crazy.bind(crazy);
这将允许您通过this
从函数访问其属性。
> crazy()
function () {
console.log(this);
console.log(this.isCrazy); // works now
}
这似乎是一个比接受的答案更好的解决方案,它使用了callee
功能,该功能已弃用且不能在严格模式下运行。
您现在也可以使用this()
以递归方式调用函数,如此倾向。
我们称之为自我暗示。写一点实用功能:
function selfthisify(fn) { return fn.bind(fn); }
crazy = selfthisify(crazy);
crazy();
或者,如果您更喜欢“语义”名称,可以将其命名为accessOwnProps
。
如果你是一个语法糖类型的人,你可以在Function原型中添加一个selfthisify
属性:
Object.defineProperty(Function.prototype, 'selfthisify', {
get: function() { return this.bind(this); }
});
现在你可以说
crazy.selfthisify();
答案 4 :(得分:3)
这必须处理函数crazy
的范围。如果可以使用函数call()
将任何范围传递给函数。
而不是
crazy();
使用
crazy.call(crazy);
详情请参阅
http://odetocode.com/blogs/scott/archive/2007/07/05/function-apply-and-function-call-in-javascript.aspx {
{3}} {
{3}}
答案 5 :(得分:2)
您可以使用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();
答案 6 :(得分:2)
如何获取要引用的功能 本身?
“本身”的概念与功能不存在。你需要的是一个对象而不仅仅是一个函数。对象通过关键字“this”可以了解自身。在一个函数中,'this'指向全局对象 - 在本例中是window对象。但是如果你使用你的函数作为构造函数来创建一个对象(使用 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
如果您希望在之前添加属性,则必须将该属性添加到函数的 prototype 中,如下所示:
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
有关代码示例的详细说明,请参阅my blog的更多信息。
答案 7 :(得分:1)
让功能本身在其身体中可用的最简单方法就是这样做
var crazy = function crazy2() { crazy2(); }
,疯狂和疯狂2可以使用相同的名称,因为第一次出现的是外部作用域中的名称,第二个是函数体中的名称。
或者只是做function crazy() { crazy(); }
,这将在两个范围内定义疯狂。
答案 8 :(得分:0)
你真的想创建一个对象'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();
答案 9 :(得分:0)
有趣的是你应该问,伙计。我刚刚完成了this same issue for a different purpose。最终代码的快速版本是:
$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
。其余的代码只是用于验证它确实按预期工作。
答案 10 :(得分:0)
为了让您的代码可以运行,请按照以下
进行操作
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);
&#13;
的属性
例如:
function speak (message) {
console.log(`A person with name ${this.name} say ${message}`);
}
speak.call({ name: 'Roland' }, 'Javascript is awesome');
&#13;
与财产一起使用:
function speak (message) {
console.log(`A person with name ${this.name} say ${message}`);
}
var name = 'Roland'
speak.call({ name }, 'Javascript is awesome');
答案 11 :(得分:0)
我个人认为,由于关键字“ this”,在函数内部使用函数的正确方法是在构造函数内部使用构造函数:
this;
定义函数并在自身内部重用它们使开发人员无法控制范围。在现实的用例中,即使一切看起来好像在自身内部调用的函数似乎都正常运行,在h * ll中也无法将其放入生产代码中。通过使用'this'关键字创建对象并将参数值分配给变量,如下所示:
new SumObj{
constructor(delta, epsilon, zeta){
this.delta = delta;
this.epsilon = epsilon;
this.zeta = zeta;
}
}
您实际上是在控制具有相同名称的变量的不同层的范围。在这种情况下,不控制变量的范围很可能引起开发人员的痛苦。
new SumObj('someStr', 300, true);
以这种方式使用对象将创建一个具有其自身唯一作用域的新实例;这使您可以信任变量的值,并且不会得到意外的结果。
class PrintObj {
constructor(obj) {
this.vals = Object.values(obj);
this.keys = Object.keys(obj);
for(let i = 0; i < this.vals.length; i++) {
const el = this.vals[i];
if(typeof el === 'object'){
new PrintObj(el);
} else {
console.log(`\t ${this.keys[i]} : ` + el);
}
}
}
}
const sumObj = {
alpha: 'Hello World!',
beta: 'Hello From Universe!',
gamma: 'Hello Developers!',
delta: {
a: '0',
b: '1',
c: '2',
e: '3',
f: '4',
},
epsilon : 'Hello Mum',
zeta : 'Hello Papa'
};
new PrintObj(sumObj);