我有一个类动态创建一个按钮,在单击它时调用输入的函数:
var TestObj = {
name: "foobar",
submit: function() {
alert("my name is: " + this.name);
},
init: function() {
$('<button>').click(function() { this.submit() }).text("hello").appendTo("#entryFormBox");
}
};
TestObj.init();
(#entryFormBox只是它进入的容器的ID。)
问题是,我收到错误:
未捕获的TypeError:this.submit不是函数
我可以猜到为什么这不起作用(当函数被赋予按钮时,“this”不再意味着“TestObj”,对吧?)。但我仍然迷失了如何以我试图让它工作的方式获得这种功能。我希望在按下按钮时正确调用提交功能。
答案 0 :(得分:0)
问题是这个是指点击回调函数。试试这个:
var TestObj = {
name: "foobar",
submit: function() {
alert("my name is: " + this.name);
},
init: function() {
var self=this;
$('<button>').click(function() { self.submit() }).text("hello").appendTo("#entryFormBox");
}
};
TestObj.init();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<dv id="entryFormBox"></div>
&#13;
关于this
关键字:
与其他语言相比,此关键字在JavaScript中的行为略有不同。它在严格模式和非严格模式之间也有一些区别。 在大多数情况下,其值取决于函数的调用方式。它不能在执行期间通过赋值来设置,并且每次调用函数时它可能不同。 ES5引入了bind方法来设置函数的值,无论它是如何被调用的,并且ES2015引入了箭头函数,这些函数的词法范围是(它被设置为封闭执行上下文的this值) )。
<强> 1。在全球范围内使用时
在全局上下文中使用this
时,它绑定到全局对象(浏览器中为window
)
document.write(this); //[object Window]
当在全局上下文中定义的函数中使用this
时,this
仍然绑定到全局对象,因为该函数实际上是一个全局上下文的方法。
function f1()
{
return this;
}
document.write(f1()); //[object Window]
以上f1
是一个全局对象的方法。因此,我们也可以在window
对象上调用它,如下所示:
function f()
{
return this;
}
document.write(window.f()); //[object Window]
<强> 2。在对象方法中使用时
在对象方法中使用this
关键字时,this
绑定到&#34;立即&#34;封闭对象。
var obj = {
name: "obj",
f: function () {
return this + ":" + this.name;
}
};
document.write(obj.f()); //[object Object]:obj
上面我已将单词立即用双引号括起来。重点是,如果将对象嵌套在另一个对象中,则this
绑定到直接父对象。
var obj = {
name: "obj1",
nestedobj: {
name:"nestedobj",
f: function () {
return this + ":" + this.name;
}
}
}
document.write(obj.nestedobj.f()); //[object Object]:nestedobj
即使您将函数显式添加到对象作为方法,它仍然遵循上述规则,即this
仍然指向直接父对象。
var obj1 = {
name: "obj1",
}
function returnName() {
return this + ":" + this.name;
}
obj1.f = returnName; //add method to object
document.write(obj1.f()); //[object Object]:obj1
第3。调用无上下文函数时
当你在没有任何上下文的情况下使用this
内部函数(即不在任何对象上)时,它被绑定到全局对象(浏览器中的window
)(即使定义了函数)在对象内部。)
var context = "global";
var obj = {
context: "object",
method: function () {
function f() {
var context = "function";
return this + ":" +this.context;
};
return f(); //invoked without context
}
};
document.write(obj.method()); //[object Window]:global
使用功能尝试所有功能
我们也可以尝试以上功能。然而,存在一些差异。
this
向函数添加成员。指定它们。new
运算符创建其实例。下面我尝试了上面用Object和this
做的所有事情,但首先是创建函数而不是直接编写对象。
/*********************************************************************
1. When you add variable to the function using this keyword, it
gets added to the function prototype, thus allowing all function
instances to have their own copy of the variables added.
*********************************************************************/
function functionDef()
{
this.name = "ObjDefinition";
this.getName = function(){
return this+":"+this.name;
}
}
obj1 = new functionDef();
document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition
/*********************************************************************
2. Members explicitly added to the function protorype also behave
as above: all function instances have their own copy of the
variable added.
*********************************************************************/
functionDef.prototype.version = 1;
functionDef.prototype.getVersion = function(){
return "v"+this.version; //see how this.version refers to the
//version variable added through
//prototype
}
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
3. Illustrating that the function variables added by both above
ways have their own copies across function instances
*********************************************************************/
functionDef.prototype.incrementVersion = function(){
this.version = this.version + 1;
}
var obj2 = new functionDef();
document.write(obj2.getVersion() + "<br />"); //v1
obj2.incrementVersion(); //incrementing version in obj2
//does not affect obj1 version
document.write(obj2.getVersion() + "<br />"); //v2
document.write(obj1.getVersion() + "<br />"); //v1
/*********************************************************************
4. `this` keyword refers to the immediate parent object. If you
nest the object through function prototype, then `this` inside
object refers to the nested object not the function instance
*********************************************************************/
functionDef.prototype.nestedObj = { name: 'nestedObj',
getName1 : function(){
return this+":"+this.name;
}
};
document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj
/*********************************************************************
5. If the method is on an object's prototype chain, `this` refers
to the object the method was called on, as if the method was on
the object.
*********************************************************************/
var ProtoObj = { fun: function () { return this.a } };
var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
//as its prototype
obj3.a = 999; //adding instance member to obj3
document.write(obj3.fun()+"<br />");//999
//calling obj3.fun() makes
//ProtoObj.fun() to access obj3.a as
//if fun() is defined on obj3
<强> 4。在构造函数内部使用时。
当函数用作构造函数时(即使用new
关键字调用它时),函数体内的this
指向正在构造的新对象。
var myname = "global context";
function SimpleFun()
{
this.myname = "simple function";
}
var obj1 = new SimpleFun(); //adds myname to obj1
//1. `new` causes `this` inside the SimpleFun() to point to the
// object being constructed thus adding any member
// created inside SimipleFun() using this.membername to the
// object being constructed
//2. And by default `new` makes function to return newly
// constructed object if no explicit return value is specified
document.write(obj1.myname); //simple function
<强> 5。在原型链中定义的函数内部使用时
如果方法在对象的原型链上,则此方法中的this
引用调用该方法的对象,就像在对象上定义了该方法一样。
var ProtoObj = {
fun: function () {
return this.a;
}
};
//Object.create() creates object with ProtoObj as its
//prototype and assigns it to obj3, thus making fun()
//to be the method on its prototype chain
var obj3 = Object.create(ProtoObj);
obj3.a = 999;
document.write(obj3.fun()); //999
//Notice that fun() is defined on obj3's prototype but
//`this.a` inside fun() retrieves obj3.a
<强> 6。内部call(),apply()和bind()函数
Function.prototype
上定义。this
的值。它们还会在调用时将任何参数传递给原始函数。答案 1 :(得分:0)
您可以使用Function.prototype.bind()
或$.proxy()
设置函数调用的this
,因为jQuery事件处理程序中的this
设置为DOM
元素默认情况下
var TestObj = {
name: "foobar",
submit: function() {
alert("my name is: " + this.name);
},
clickHandler: function() {
this.submit()
},
init: function() {
$('<button>').click(this.clickHandler.bind(this))
.text("hello")
.appendTo("#entryFormBox");
}
};
TestObj.init();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="entryFormBox"></div>
&#13;
var TestObj = {
name: "foobar",
submit: function() {
alert("my name is: " + this.name);
},
init: function() {
$('<button>').click(
$.proxy(function() {
this.submit()
}, this)
)
.text("hello")
.appendTo("#entryFormBox");
}
};
TestObj.init();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="entryFormBox"></div>
&#13;
答案 2 :(得分:-1)
试试这个:
var TestObj = {
name: "foobar",
submit: function() {
alert("my name is: " + this.name);
},
init: function() {
$('<button>').click(function() { TestObj.submit() }).text("hello").appendTo("#entryFormBox");
}
};
TestObj.init();