我注意到,似乎没有明确说明this
关键字是什么以及如何在Stack Overflow站点上的JavaScript中正确(和错误地)使用它。
我目睹了一些非常奇怪的行为,并且无法理解为什么会发生这种行为。
this
如何运作以及何时使用?
答案 0 :(得分:1254)
答案 1 :(得分:138)
与其他语言相比,this
关键字在JavaScript中的行为有所不同。在面向对象语言中,this
关键字引用类的当前实例。在JavaScript中,this
的值主要取决于函数的调用上下文( context.function()
)以及调用它的位置。
<强> 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
的值。它们还会在调用时将任何参数传递给原始函数。fun.apply(obj1 [, argsArray])
将obj1
设置为this
内fun()
的值,并调用fun()
传递argsArray
的元素}作为其论点。fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- 将obj1
设置为this
内fun()
的值,并通过fun()
调用arg1, arg2, arg3, ...
作为其论点。fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- 返回对fun
函数的引用,其中this
位于obj1
和fun
的参数范围内绑定到指定的参数arg1, arg2, arg3,...
。apply
,call
和bind
之间的区别必须明显。 apply
允许指定用作类数组对象的参数,即具有数字length
属性的对象和相应的非负整数属性。而call
允许直接指定函数的参数。 apply
和call
都会立即调用指定上下文中的函数并使用指定的参数。另一方面,bind
只返回绑定到指定this
值和参数的函数。我们可以通过将其分配给变量来捕获对此返回函数的引用,之后我们可以随时调用它。function add(inc1, inc2)
{
return this.a + inc1 + inc2;
}
var o = { a : 4 };
document.write(add.call(o, 5, 6)+"<br />"); //15
//above add.call(o,5,6) sets `this` inside
//add() to `o` and calls add() resulting:
// this.a + inc1 + inc2 =
// `o.a` i.e. 4 + 5 + 6 = 15
document.write(add.apply(o, [5, 6]) + "<br />"); //15
// `o.a` i.e. 4 + 5 + 6 = 15
var g = add.bind(o, 5, 6); //g: `o.a` i.e. 4 + 5 + 6
document.write(g()+"<br />"); //15
var h = add.bind(o, 5); //h: `o.a` i.e. 4 + 5 + ?
document.write(h(6) + "<br />"); //15
// 4 + 5 + 6 = 15
document.write(h() + "<br />"); //NaN
//no parameter is passed to h()
//thus inc2 inside add() is `undefined`
//4 + 5 + undefined = NaN</code>
<强> 7。事件处理程序中的this
this
指的是相应的元素。这种直接函数分配可以使用addeventListener
方法或通过onclick
等传统事件注册方法完成。this
)内直接使用<button onclick="...this..." >
时,它会引用该元素。this
会解析为全局对象window
。attachEvent
将函数附加到事件处理程序时,可以实现相同的上述行为。它不是将函数赋值给事件处理程序(从而构成元素的函数方法),而是调用事件上的函数(在全局上下文中有效地调用它)。我建议您最好在JSFiddle中尝试此操作。
<script>
function clickedMe() {
alert(this + " : " + this.tagName + " : " + this.id);
}
document.getElementById("button1").addEventListener("click", clickedMe, false);
document.getElementById("button2").onclick = clickedMe;
document.getElementById("button5").attachEvent('onclick', clickedMe);
</script>
<h3>Using `this` "directly" inside event handler or event property</h3>
<button id="button1">click() "assigned" using addEventListner() </button><br />
<button id="button2">click() "assigned" using click() </button><br />
<button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>
<h3>Using `this` "indirectly" inside event handler or event property</h3>
<button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />
<button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />
IE only: <button id="button5">click() "attached" using attachEvent() </button>
答案 2 :(得分:54)
this
考虑以下功能:
function foo() {
console.log("bar");
console.log(this);
}
foo(); // calling the function
请注意,我们在正常模式下运行它,即不使用严格模式。
在浏览器中运行时,this
的值将记录为window
。这是因为window
是Web浏览器范围内的全局变量。
如果您在node.js这样的环境中运行同一段代码,this
会引用您应用中的全局变量。
现在,如果我们在严格模式下通过将语句"use strict";
添加到函数声明的开头来运行它,this
将不再引用任何环境中的全局变量。这样做是为了避免严格模式下的混淆。在这种情况下,this
只会记录undefined
,因为它就是这样,它没有被定义。
在以下情况中,我们将看到如何操纵this
。
有不同的方法可以做到这一点。如果您在forEach
和slice
等Javascript中调用了本机方法,那么您应该已经知道this
变量在这种情况下引用了您调用该函数的Object
(请注意,在javascript中,几乎所有内容都是Object
,包括Array
和Function
s。以下面的代码为例。
var myObj = {key: "Obj"};
myObj.logThis = function () {
// I am a method
console.log(this);
}
myObj.logThis(); // myObj is logged
如果Object
包含一个包含Function
的属性,则该属性称为方法。调用此方法时,将始终将this
变量设置为与其关联的Object
。对于严格和非严格模式都是如此。
请注意,如果方法存储(或者更确切地说,复制)在另一个变量中,则对this
的引用不再保留在新变量中。例如:
// continuing with the previous code snippet
var myVar = myObj.thisMethod;
myVar();
// logs either of window/global/undefined based on mode of operation
考虑更常见的实际情况:
var el = document.getElementById('idOfEl');
el.addEventListener('click', function() { console.log(this) });
// the function called by addEventListener contains this as the reference to the element
// so clicking on our element would log that element itself
new
关键字考虑Javascript中的构造函数:
function Person (name) {
this.name = name;
this.sayHello = function () {
console.log ("Hello", this);
}
}
var awal = new Person("Awal");
awal.sayHello();
// In `awal.sayHello`, `this` contains the reference to the variable `awal`
这是如何工作的?好吧,让我们看看当我们使用new
关键字时会发生什么。
new
关键字调用该函数会立即初始化Object
类型Person
。Object
的构造函数的构造函数设置为Person
。另请注意,typeof awal
仅返回Object
。Object
将被分配Person.prototype
的原型。这意味着Person
原型中的任何方法或属性都可用于Person
的所有实例,包括awal
。Person
本身; this
是对新构造的对象awal
的引用。非常简单,嗯?
请注意,官方的ECMAScript规范没有说明这类函数是实际的constructor
函数。它们只是普通函数,new
可用于任何函数。只是我们这样使用它们,因此我们只将它们称为它们。
call
和apply
所以是的,既然function
也是Objects
(实际上是Javascript中的第一类变量),甚至函数都有......好吧,函数本身。
所有功能都从全局Function
继承,其中有两种方法是call
和apply
,两者都可用于操纵this
的值它们被称为的函数。
function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);
这是使用call
的典型示例。它基本上采用第一个参数,并在函数this
中设置foo
作为对thisArg
的引用。传递给call
的所有其他参数作为参数传递给函数foo
因此,上面的代码将在控制台中记录{myObj: "is cool"}, [1, 2, 3]
。在任何函数中更改this
的值的非常好的方法。
apply
与call
几乎相同,只接受两个参数:thisArg
和一个包含要传递给函数的参数的数组。因此,上述call
调用可以像这样翻译为apply
:
foo.apply(thisArg, [1,2,3])
请注意,call
和apply
可以覆盖我们在第二个项目符号中讨论的点方法调用设置的this
的值。
很简单:)
bind
! bind
是call
和apply
的兄弟。它也是Javascript中全局Function
构造函数的所有函数继承的方法。 bind
和call
/ apply
之间的区别在于call
和apply
实际上都会调用该函数。另一方面,bind
会返回一个预设thisArg
和arguments
的新函数。让我们举一个例子来更好地理解这一点:
function foo (a, b) {
console.log (this, arguments);
}
var thisArg = {myObj: "even more cool now"};
var bound = foo.bind(thisArg, 1, 2);
console.log (typeof bound); // logs `function`
console.log (bound);
/* logs `function () { native code }` */
bound(); // calling the function returned by `.bind`
// logs `{myObj: "even more cool now"}, [1, 2]`
看到三者之间的区别?它很微妙,但它们的使用方式不同。与call
和apply
一样,bind
也会覆盖由点方法调用设置的this
值。
另请注意,这三个功能都不会对原始功能进行任何更改。 call
和apply
将从新构造的函数返回值,而bind
将返回新构造的函数本身,随时可以调用。
有时,您不喜欢this
随范围变化的事实,尤其是嵌套范围。看一下下面的例子。
var myObj = {
hello: function () {
return "world"
},
myMethod: function () {
// copy this, variable names are case-sensitive
var that = this;
// callbacks ftw \o/
foo.bar("args", function () {
// I want to call `hello` here
this.hello(); // error
// but `this` references to `foo` damn!
// oh wait we have a backup \o/
that.hello(); // "world"
});
}
};
在上面的代码中,我们看到this
的值随嵌套范围而变化,但我们希望原始范围内的this
值。所以我们复制了#39; this
到that
并使用了副本而不是this
。聪明,嗯?
指数:
this
中的内容是什么?new
关键字this
和call
操纵apply
?bind
。this
以解决嵌套范围问题。答案 3 :(得分:46)
“这个”就是范围。每个函数都有自己的作用域,因为JS中的所有东西都是一个对象,所以即使函数也可以使用“this”将一些值存储到自身中。 OOP 101教导“this”仅适用于对象的实例。因此,每次执行一个函数时,该函数的新“实例”都具有“this”的新含义。
大多数人在尝试在匿名闭包函数中使用“this”时会感到困惑:
(function(value) { this.value = value; $('.some-elements').each(function(elt){ elt.innerHTML = this.value; // uh oh!! possibly undefined }); })(2);
所以在这里,在每个()中,“this”不包含你期望它的“值”(从它上面的
this.value = value;)。因此,为了克服这个问题(没有双关语)问题,开发人员可以:
(function(value) { var self = this; // small change self.value = value; $('.some-elements').each(function(elt){ elt.innerHTML = self.value; // phew!! == 2 }); })(2);
尝试一下;你会开始喜欢这种编程模式
答案 4 :(得分:16)
由于这个帖子已经出现问题,我已经为刚接触this
主题的读者编了几点。
this
的值是如何确定的?我们使用类似于我们在英语等自然语言中使用代词的方式:“约翰跑得快,因为 他 正试图赶上火车。”相反,我们本来可以写“...... John 正试图赶上火车”。
var person = {
firstName: "Penelope",
lastName: "Barrymore",
fullName: function () {
// We use "this" just as in the sentence above:
console.log(this.firstName + " " + this.lastName);
// We could have also written:
console.log(person.firstName + " " + person.lastName);
}
}
在对象调用定义它的函数之前, this
未分配值。在全局范围内,所有全局变量和函数都在window
对象上定义。因此,全局函数中的this
引用全局window
对象(并具有其值)。
use strict
时,未绑定到任何对象的全局和匿名函数中的this
值为undefined
。
this
关键字为most misunderstood时:1)我们借用了使用this
的方法,2)我们为变量分配了一个使用this
的方法,3 )使用this
的函数作为回调函数传递,4)this
在闭包内部使用 - 内部函数。 (2)
在ECMA Script 6中定义,箭头函数采用来自的this
绑定
封闭(功能或全局)范围。
function foo() {
// return an arrow function
return (a) => {
// `this` here is lexically inherited from `foo()`
console.log(this.a);
};
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };
var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!
虽然箭头函数提供了使用bind()
的替代方法,但重要的是要注意它们基本上禁用传统的this
机制,以支持更广泛理解的词法范围。 (1)
<强> 参考文献: 强>
答案 5 :(得分:16)
this
始终指的是正在执行的函数的“所有者”。
如果未定义显式所有者,则引用最顶层的所有者即窗口对象。
所以,如果我做了
function someKindOfFunction() {
this.style = 'foo';
}
element.onclick = someKindOfFunction;
this
将引用元素对象。但要小心,很多人犯了这个错误
<element onclick="someKindOfFunction()">
在后一种情况下,您只需引用该函数,而不是将其移交给元素。因此,this
将引用窗口对象。
答案 6 :(得分:12)
javascript中的每个函数 执行上下文都有范围 上下文 此参数由以下人员设定:
无论范围上下文是什么,都以“this”引用。
您可以使用设置此 func.call
更改范围 context 的值,{ {1}}或func.apply
。
默认情况下,大多数初学者都会感到困惑,当在DOM元素上引发事件后调用回调侦听器时,范围上下文 this < / em>函数的值是DOM元素。
jQuery使用jQuery.proxy来改变这一点。
答案 7 :(得分:10)
Here是this
中JavaScript
的一个很好的来源。
以下是摘要:
全球
在浏览器中,在全局范围内,this
是window
对象
<script type="text/javascript">
console.log(this === window); // true
var foo = "bar";
console.log(this.foo); // "bar"
console.log(window.foo); // "bar"
在使用repl的node
中,this
是顶级命名空间。您可以将其称为global
。
>this
{ ArrayBuffer: [Function: ArrayBuffer],
Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
...
>global === this
true
在node
执行脚本时,全局范围内的this
作为空对象开始。它与global
\\test.js
console.log(this); \\ {}
console.log(this === global); \\ fasle
此功能
除了DOM事件处理程序或提供thisArg
时(参见下文),在节点和浏览器中使用this
的函数都未使用{{ 1}}引用全局范围......
new
如果您使用<script type="text/javascript">
foo = "bar";
function testThis() {
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis();
console.log(this.foo); //logs "foo"
</script>
,则use strict;
将this
undefined
如果您使用<script type="text/javascript">
foo = "bar";
function testThis() {
"use strict";
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
testThis(); //Uncaught TypeError: Cannot set property 'foo' of undefined
</script>
调用某个函数,则new
将成为新的上下文,它将不会引用全局this
。
this
您创建的函数将成为函数对象。它们会自动获得一个特殊的<script type="text/javascript">
foo = "bar";
function testThis() {
this.foo = "foo";
}
console.log(this.foo); //logs "bar"
new testThis();
console.log(this.foo); //logs "bar"
console.log(new testThis().foo); //logs "foo"
</script>
属性,您可以为其赋值。通过使用prototype
调用函数创建实例时,您可以访问分配给new
属性的值。您可以使用prototype
访问这些值。
this
在function Thing() {
console.log(this.foo);
}
Thing.prototype.foo = "bar";
var thing = new Thing(); //logs "bar"
console.log(thing.foo); //logs "bar"
上分配数组或对象通常是错误的。如果您希望每个实例都有自己的数组,请在函数中创建它们,而不是原型。
prototype
您可以在对象的任何函数中使用function Thing() {
this.things = [];
}
var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
来引用该对象上的其他属性。这与使用this
创建的实例不同。
new
在HTML DOM事件处理程序中,var obj = {
foo: "bar",
logFoo: function () {
console.log(this.foo);
}
};
obj.logFoo(); //logs "bar"
始终是对事件附加到的DOM元素的引用
this
除非你function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick);
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs "<div id="foo"></div>"
}
var listener = new Listener();
document.getElementById("foo").click();
上下文
bind
在您可以放置JavaScript的HTML内部属性中,function Listener() {
document.getElementById("foo").addEventListener("click",
this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
console.log(this); //logs Listener {handleClick: function}
}
var listener = new Listener();
document.getElementById("foo").click();
是对元素的引用。
this
您可以使用<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
访问eval
。
this
您可以使用function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
eval("console.log(this.foo)"); //logs "bar"
}
var thing = new Thing();
thing.logFoo();
将with
添加到当前范围,以便在this
上读取和写入值,而无需明确引用this
。
this
jQuery将在很多地方function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
with (this) {
console.log(foo);
foo = "foo";
}
}
var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
引用DOM元素。
this
答案 8 :(得分:9)
this
执行上下文指针的良好列表上的几个单词。
用两个词来说,JavaScript中的this
指向运行当前函数的对象(或从其执行上下文),并且它始终是只读的,无论如何都无法设置它(这样的尝试将会以“分配中无效的左侧”消息结束。
对于事件处理程序:内联事件处理程序(例如<element onclick="foo">
)会覆盖之前和之前附加的任何其他处理程序,因此请务必小心,最好不要使用内联事件委派。
感谢Zara Alaverdyan,他通过不同的辩论激发了我对这个例子的启发:)
el.onclick = foo; // in the foo - obj
el.onclick = function () {this.style.color = '#fff';} // obj
el.onclick = function() {doSomething();} // In the doSomething -
Window
el.addEventListener('click',foo,false) // in the foo - obj
el.attachEvent('onclick, function () { // this }') // window, all the
compliance to IE :)
<button onclick="this.style.color = '#fff';"> // obj
<button onclick="foo"> // In the foo - window, but you can <button
onclick="foo(this)">
答案 9 :(得分:9)
关于this
的最详细和最全面的文章可能如下:
Gentle explanation of 'this' keyword in JavaScript
this
背后的想法是要理解函数调用类型对设置this
值具有重要意义。
如果遇到问题this
,不问自己:
this
取自?
但做问自己:
如何调用函数?
对于箭头功能(上下文透明度的特殊情况),请问自己:
箭头函数定义的哪个值为
this
?
在处理this
时,这种心态是正确的,并且可以免除头痛。
答案 10 :(得分:9)
关于如何在JavaScript中解释&#34;此&#34; 关键字存在很多混淆。希望这篇文章能够让所有人一劳永逸地休息。还有更多。请仔细阅读整篇文章。预先警告这篇文章很长。
无论使用它的上下文如何,&#34;此&#34; 始终引用Javascript中的&#34;当前对象&#34; 。但是,&#34;当前对象&#34; 根据上下文而有所不同。 上下文可能正好是以下中的中的一个
。以下逐一描述每个上下文:
全球背景(即所有功能之外):
在所有功能之外(即在全局范围内)&#34;当前 对象&#34; (因此&#34;这个&#34; 的值)始终是 浏览器的&#34;窗口&#34; 对象。
内部直接&#34;非约束功能&#34;致电:
直接&#34;非约束功能&#34;打电话,那个对象 调用函数调用成为&#34;当前对象&#34; (因此 &#34;此&#34; )的值。如果在没有明确当前对象的情况下调用函数,则当前对象是&#34;窗口&#34; 对象(对于非严格模式)或未定义(适用于严格模式)。中定义的任何函数(或变量) 全局上下文会自动成为&#34;窗口&#34; 对象的属性。例如假设函数在全局上下文中定义为
function UserDefinedFunction(){
alert(this)
}
它成为窗口对象的属性,就像你已经定义了一样 它是
window.UserDefinedFunction=function(){
alert(this)
}
在&#34;非严格模式&#34;,直接通过&#34; UserDefinedFunction()&#34; 调用/调用此功能将自动调用/调用 它作为&#34; window.UserDefinedFunction()&#34; 使&#34;窗口&#34; 作为 &#34;当前对象&#34; (以及&#34;此&#34; 的值)&#34; UserDefinedFunction&#34; 。在&#34;非严格模式&#34;中调用此功能将导致以下
UserDefinedFunction() // displays [object Window] as it automatically gets invoked as window.UserDefinedFunction()
在&#34;严格模式&#34;,直接通过调用/调用函数 &#34; UserDefinedFunction()&#34; 将&#34; NOT&#34; 自动调用/调用它作为&#34; window.UserDefinedFunction ()&#34; 。&#34;当前 对象&#34; (以及&#34;此&#34; 的值) &#34; UserDefinedFunction&#34; 应未定义。在&#34;严格模式&#34;中调用此功能将导致以下
UserDefinedFunction() // displays undefined
但是,使用window对象显式调用它会导致 以下
window.UserDefinedFunction() // "always displays [object Window] irrespective of mode."
让我们看看另一个例子。请查看以下代码
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction
}
var o2={
c:3,
d:4,
f:UserDefinedFunction
}
o1.f() // Shall display 1,2,undefined,undefined
o2.f() // Shall display undefined,undefined,3,4
在上面的示例中,我们看到&#34; UserDefinedFunction&#34; 是 通过 o1 ,&#34进行调用;此&#34; 取值 o1 和 其属性值&#34; a&#34; 和&#34; b&#34; 会显示。价值 &#34; c&#34; 和&#34; d&#34; 显示为未定义为 o1 强>做 没有定义这些属性
同样,当&#34; UserDefinedFunction&#34; 通过 o2 调用时, &#34;此&#34; 取值 o2 及其属性值&#34; c&#34; 和&#34; d&#34; 显示。&#34; a&#34; 和&#34; b&#34; 的值显示为未定义,因为 o2 未定义这些属性。
内部间接&#34;非约束功能&#34;通过 functionName.call 和 functionName.apply 致电:
当调用&#34;非约束函数&#34; 时 functionName.call 或 functionName.apply ,&#34;当前对象&#34; < / strong>(因此&#34;此&#34; 的值)设置为值 &#34;此&#34; 参数(第一个参数)传递给调用/应用。以下代码演示了相同的内容。
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction
}
var o2={
c:3,
d:4,
f:UserDefinedFunction
}
UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined
UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined
UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4
UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4
o1.f.call(o2) // Shall display undefined,undefined,3,4
o1.f.apply(o2) // Shall display undefined,undefined,3,4
o2.f.call(o1) // Shall display 1,2,undefined,undefined
o2.f.apply(o1) // Shall display 1,2,undefined,undefined
上面的代码清楚地表明了这个&#34;这个&#34;任何&#34; NON的价值 绑定功能&#34;可以通过呼叫/应用进行更改。另外,如果 &#34;此&#34; 参数未明确传递给调用/应用,&#34;当前对象&#34; (和因此&#34;此&#34;)的值在非严格模式下设置为&#34; window&#34; ,&#34; undefined&#34; 严格模式。
内部&#34;绑定功能&#34;调用(即通过调用 functionName.bind 绑定的函数):
绑定函数是&#34;此&#34; 值的函数 固定。以下代码演示了&#34;此&#34; 的工作原理 绑定函数
function UserDefinedFunction()
{
alert(this.a + "," + this.b + "," + this.c + "," + this.d)
}
var o1={
a:1,
b:2,
f:UserDefinedFunction,
bf:null
}
var o2={
c:3,
d:4,
f:UserDefinedFunction,
bf:null
}
var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1
bound1() // Shall display 1,2,undefined,undefined
var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2
bound2() // Shall display undefined,undefined,3,4
var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2
bound3() // Shall display undefined,undefined,3,4
var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1
bound4() // Shall display 1,2,undefined,undefined
o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2
o1.bf() // Shall display undefined,undefined,3,4
o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1
o2.bf() // Shall display 1,2,undefined,undefined
bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function
o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function
如上面的代码所示,&#34; this&#34;任何&#34;绑定功能&#34;的值 不能通过电话/申请进行更改。此外,如果&#34;此&#34; 参数未明确传递给bind,&#34;当前对象&#34; (因此&#34;此&#34; )的值设置为非&#34;窗口&#34; 在严格模式下严格模式和&#34; undefined&#34; 。还有一件事。 绑定已绑定的函数不会更改&#34;此&#34; 的值。 它仍然设置为第一个绑定函数设置的值。
通过&#34; new&#34; 创建对象时:
在构造函数内部,&#34;当前对象&#34; (因此值 &#34;此&#34; )引用当前正在创建的对象 通过&#34; new&#34; ,无论函数的绑定状态如何。然而 如果构造函数是一个绑定函数,它将被调用 为绑定函数设置的预定义参数集。
内联DOM事件处理程序:
请查看以下HTML代码段
<button onclick='this.style.color=white'>Hello World</button>
<div style='width:100px;height:100px;' onclick='OnDivClick(event,this)'>Hello World</div>
以上示例中的&#34;此&#34; 是指&#34;按钮&#34;元素和 &#34; DIV&#34;元素分别。
在第一个示例中,按钮的字体颜色应设置为 单击时为白色。
在第二个例子中,当点击&#34; div&#34; 元素时 使用第二个参数调用 OnDivClick 函数 引用单击的div元素。但是&#34;这个&#34; 的价值 在OnDivClick中不会引用点击的 div 元件。它应设置为&#34;窗口对象&#34; 或 分别在非严格和严格模式中&#34; undefined&#34; (如果 OnDivClick 是未绑定功能)或设置为预定义 绑定值(如果 OnDivClick 是绑定函数)
以下总结了整篇文章
在全球背景下&#34;此&#34; 始终引用&#34;窗口&#34; 对象
每当调用一个函数时,都会在一个函数的上下文中调用它 对象(&#34;当前对象&#34; )。如果未明确提供当前对象, 当前对象是 NON Strict中的&#34;窗口对象&#34; 默认情况下,模式和&#34;未定义&#34; 在严格模式下。
非强制函数中&#34;此&#34; 的值是在调用函数的上下文中对象的引用(&#34;当前对象&#34; )
非强制功能中&#34;此&#34; 的值可以被覆盖 调用和应用函数的方法。
&#34;此&#34; 的值对于Bound函数是固定的,不能是 通过调用和应用函数方法覆盖。
绑定和已绑定的函数不会更改&#34;这个&#34;的值。它仍然设置为第一个绑定函数设置的值。
构造函数中&#34; this&#34; 的值是正在的对象 创建并初始化
内联DOM事件处理程序中&#34; this&#34; 的值是引用 到给出事件处理程序的元素。
答案 11 :(得分:7)
这是我见过的最好的解释。 Understand JavaScripts this with Clarity
this 引用始终引用(并保存)a的值 object - 一个单数对象 - 它通常用在一个函数或一个函数中 方法,虽然它可以在全局函数之外使用 范围。请注意,当我们使用严格模式时,它保持值 在全局函数和非匿名函数中未定义 绑定到任何对象。
这个有四个条件可能令人困惑:
他提供了我认为非常有用的代码示例,解释和代码修复。
答案 12 :(得分:6)
如果你不完全理解JS,很难掌握JS,或者写出更多的东西。你不能只是快花钱:)我认为开始使用JS的最佳方式是首先观看Douglas Crockford撰写的这些视频讲座 - http://yuiblog.com/crockford/,其中涵盖了这个和那个,以及关于JS的所有其他内容。
答案 13 :(得分:6)
在伪古典术语中,许多讲座教授'this'关键字的方式是作为由类或对象构造函数实例化的对象。每次从一个类构造一个新对象时,想象一下,创建并返回一个'this'对象的本地实例。我记得它是这样教的:
function Car(make, model, year) {
var this = {}; // under the hood, so to speak
this.make = make;
this.model = model;
this.year = year;
return this; // under the hood
}
var mycar = new Car('Eagle', 'Talon TSi', 1993);
// ========= under the hood
var this = {};
this.make = 'Eagle';
this.model = 'Talon TSi';
this.year = 1993;
return this;
答案 14 :(得分:5)
this
是JavaScript中被误解的概念之一,因为它在不同地方的行为方式略有不同。简单来说,this
是指&#34;所有者&#34;我们当前正在执行的功能。
this
有助于获取我们使用的当前对象(a.k.a.执行上下文)。如果您了解当前函数在哪个对象中执行,您可以轻松理解当前this
是什么
var val = "window.val"
var obj = {
val: "obj.val",
innerMethod: function () {
var val = "obj.val.inner",
func = function () {
var self = this;
return self.val;
};
return func;
},
outerMethod: function(){
return this.val;
}
};
//This actually gets executed inside window object
console.log(obj.innerMethod()()); //returns window.val
//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val
console.log(obj.outerMethod()); //returns obj.val
上面我们创建了3个同名的变量&#39; val&#39;。一个在全局上下文中,一个在obj中,另一个在obj的innerMethod中。 JavaScript通过从本地go全局上升范围链来解析特定上下文中的标识符。
可以区分this
的几个地方
var status = 1;
var helper = {
status : 2,
getStatus: function () {
return this.status;
}
};
var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2
var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1
当执行line1时,JavaScript为函数调用建立一个执行上下文(EC),将this
设置为前一个&#34;之前所引用的对象。&#34; < / strong>即可。所以在最后一行你可以理解a()
是在全局上下文中执行的window
。
this
可用于指代正在创建的对象
function Person(name){
this.personName = name;
this.sayHello = function(){
return "Hello " + this.personName;
}
}
var person1 = new Person('Scott');
console.log(person1.sayHello()); //Hello Scott
var person2 = new Person('Hugh');
var sayHelloP2 = person2.sayHello;
console.log(sayHelloP2()); //Hello undefined
执行新的Person()
时,会创建一个全新的对象。调用Person
并将其this
设置为引用该新对象。
function testFunc() {
this.name = "Name";
this.myCustomAttribute = "Custom Attribute";
return this;
}
var whatIsThis = testFunc();
console.log(whatIsThis); //window
var whatIsThis2 = new testFunc();
console.log(whatIsThis2); //testFunc() / object
console.log(window.myCustomAttribute); //Custom Attribute
如果我们错过new
个关键字,whatIsThis
会引用它可以找到的最全局的上下文(window
)
如果事件处理程序是内联的,this
引用全局对象
<script type="application/javascript">
function click_handler() {
alert(this); // alerts the window object
}
</script>
<button id='thebutton' onclick='click_handler()'>Click me!</button>
通过JavaScript添加事件处理程序时,this
引用生成事件的DOM元素。
.apply()
.call()
和.bind()
var that = this
means in JavaScript 答案 15 :(得分:5)
“this”的值取决于执行函数的“context”。上下文可以是任何对象或全局对象,即窗口。
因此“this”的语义与传统的OOP语言不同。它会导致问题: 1.当函数传递给另一个变量时(很可能是一个回调); 2.当从类的成员方法调用闭包时。
在这两种情况下,都设置为窗口。
答案 16 :(得分:3)
Whould this有帮助吗? (javascript中对'this'的大多数混淆来自于它通常没有链接到你的对象,而是链接到当前的执行范围 - 这可能不是它的工作方式,但总是对我来说 - 请参阅文章以获得完整的解释)
答案 17 :(得分:3)
有关此关键字
的一些信息让我们在全局范围内将this
关键字登录到控制台,但没有任何其他代码
console.log(this)
在客户端/浏览器中,this
关键字是一个全局对象,它是window
console.log(this === window) // true
和
在服务器/节点/ JavaScript运行时中,this
关键字也是一个全局对象,它是module.exports
console.log(this === module.exports) // true
console.log(this === exports) // true
请紧记exports
只是对module.exports
的引用
答案 18 :(得分:1)
就像这样使用Scope
<script type="text/javascript" language="javascript">
$('#tbleName tbody tr').each(function{
var txt='';
txt += $(this).find("td").eq(0).text();
\\same as above but synatx different
var txt1='';
txt1+=$('#tbleName tbody tr').eq(0).text();
alert(txt1)
});
</script>
txt1和txt的值相同 在上面的例子中 $(this)= $('#tbleName tbody tr')是相同的
答案 19 :(得分:1)
我对this
的看法与我希望有帮助的其他答案不同。
查看JavaScript的一种方法是看到只有一种方法可以调用函数 1 。是
functionObject.call(objectForThis, arg0, arg1, arg2, ...);
始终为objectForThis
提供一些值。
所有其他内容都是functionObject.call
的语法糖
因此,其他所有内容都可以通过其翻译成functionObject.call
的方式来描述。
如果仅调用函数,则this
是“全局对象”,在浏览器中是窗口
function foo() {
console.log(this);
}
foo(); // this is the window object
换句话说
foo();
被有效地翻译为
foo.call(window);
请注意,如果您使用严格模式,则this
将是undefined
'use strict';
function foo() {
console.log(this);
}
foo(); // this is the window object
这意味着
换句话说
foo();
被有效地翻译为
foo.call(undefined);
JavaScript中有+
和-
和*
之类的运算符。还有一个点运算符为.
.
运算符与右侧的函数和左侧的对象一起使用时,实际上意味着“将对象作为this
传递给函数。
示例
const bar = {
name: 'bar',
foo() {
console.log(this);
},
};
bar.foo(); // this is bar
换句话说,bar.foo()
转换为const temp = bar.foo; temp.call(bar);
请注意,函数的创建方式无关紧要(主要是...)。所有这些都会产生相同的结果
const bar = {
name: 'bar',
fn1() { console.log(this); },
fn2: function() { console.log(this); },
fn3: otherFunction,
};
function otherFunction() { console.log(this) };
bar.fn1(); // this is bar
bar.fn2(); // this is bar
bar.fn3(); // this is bar
这些都是语法糖
{ const temp = bar.fn1; temp.call(bar); }
{ const temp = bar.fn2; temp.call(bar); }
{ const temp = bar.fn3; temp.call(bar); }
原型皱纹是另一个皱纹。当您使用a.b
时,JavaScript首先会在a
直接引用的对象上查找属性b
。如果在对象上未找到b
,则JavaScript将在对象的原型中查找以找到b
。
定义对象原型的方法有很多种,2019年最常见的是class
关键字。就this
而言,这无关紧要。重要的是,如果它在对象a
的对象b
上找到了属性b
,或者在原型链中找到了b
,那么它在对象b
中查找为函数,适用与上述相同的规则。函数call
的引用将使用a
方法,并将this
作为objectForThis传递,如答案顶部所示。
现在。假设我们创建了一个在调用另一个函数之前先显式设置.
的函数,然后使用function foo() {
console.log(this);
}
function bar() {
const objectForThis = {name: 'moo'}
foo.call(objectForThis); // explicitly passing objectForThis
}
const obj = {
bar,
};
obj.bar();
(点)运算符
call
翻译后使用obj.bar()
,const temp = obj.bar; temp.call(obj);
变成bar
。当我们输入foo
函数时,我们将调用this
,但是我们为objectForThis显式传递了另一个对象,因此,当我们到达foo bind
时就是该内部对象。
这是=>
和bar
函数有效执行的操作。它们是语法更多的糖。他们有效地构建了一个新的不可见函数,就像上面的this
一样,它在调用指定的任何函数之前显式设置了this
。对于绑定bind
设置为您传递给function foo() {
console.log(this);
}
const bar = foo.bind({name: 'moo'});
// bind created a new invisible function that calls foo with the bound object.
bar();
// the objectForThis we are passing to bar here is ignored because
// the invisible function that bind created will call foo with with
// the object we bound above
bar.call({name: 'other'});
的任何值。
functionObject.bind
请注意,如果function bind(fn, objectForThis) {
return function(...args) {
return fn.call(objectForthis, ...args);
};
}
不存在,我们可以像这样
function foo() {
console.log(this);
}
const bar = bind(foo, {name:'abc'});
然后我们可以这样称呼
=>
箭头功能,const a = () => {console.log(this)};
运算符是bind的语法糖
const tempFn = function() {console.log(this)};
const a = tempFn.bind(this);
与
相同bind
就像objectForThis
一样,创建了一个新的不可见函数,该函数用给定的bind
绑定值调用给定函数,但是与this
不同,要绑定的对象是隐式的。使用=>
运算符时,const a = () => { console.log(this); } // this is the global object
都会发生这种情况。
所以,就像上面的规则
'use strict';
const a = () => { console.log(this); } // this is undefined
function foo() {
return () => { console.log(this); }
}
const obj = {
foo,
};
const b = obj.foo();
b();
obj.foo()
const temp = obj.foo; temp.call(obj);
转换为foo
,这意味着obj
中的箭头运算符会将b
绑定到一个新的不可见函数,并返回分配给{{ 1}}。 b()
将像b.call(window)
或b.call(undefined)
一样调用foo
创建的新的不可见函数。这个不可见的函数会忽略传递给它的this
并将obj
作为objectForThis`传递给箭头函数。
上面的代码翻译为
function foo() {
function tempFn() {
console.log(this);
}
return tempFn.bind(this);
}
const obj = {
foo,
};
const b = obj.foo();
b.call(window or undefined if strict mode);
1 apply
是类似于call
functionName.apply(objectForThis, arrayOfArgs);
但是从ES6的概念上讲,您甚至可以将其翻译成
functionName.call(objectForThis, ...arrayOfArgs);
答案 20 :(得分:0)
this
Javascript:this
的值由如何不调用函数,在何处创建函数来确定! this
的值由点左侧的对象确定。 (window
在全球空间中)this
的值表示在其上调用事件的DOM元素。new
关键字调用in函数时,this
的值引用新创建的对象this
的值:call
,apply
,bind
let object = {
prop1: function () {console.log(this);}
}
object.prop1(); // object is left of the dot, thus this is object
const myFunction = object.prop1 // We store the function in the variable myFunction
myFunction(); // Here we are in the global space
// myFunction is a property on the global object
// Therefore it logs the window object
document.querySelector('.foo').addEventListener('click', function () {
console.log(this); // This refers to the DOM element the eventListener was invoked from
})
document.querySelector('.foo').addEventListener('click', () => {
console.log(this); // Tip, es6 arrow function don't have their own binding to the this v
}) // Therefore this will log the global object
.foo:hover {
color: red;
cursor: pointer;
}
<div class="foo">click me</div>
function Person (name) {
this.name = name;
}
const me = new Person('Willem');
// When using the new keyword the this in the constructor function will refer to the newly created object
console.log(me.name);
// Therefore, the name property was placed on the object created with new keyword.
答案 21 :(得分:0)
JavaScript中的“ this”关键字是什么
此关键字指的是一个对象,该对象正在执行javascript代码的当前位。
换句话说,每个JavaScript函数在执行时都会引用其当前执行上下文,称为this。执行上下文意味着这里是函数的调用方式。
要理解此关键字,只需要知道如何,何时何地从何处调用函数,与如何在何处声明或定义函数无关。
function bike() {
console.log(this.name);
}
var name = "Ninja";
var obj1 = { name: "Pulsar", bike: bike };
var obj2 = { name: "Gixxer", bike: bike };
bike(); // "Ninja"
obj1.bike(); // "Pulsar"
obj2.bike(); // "Gixxer"
在上述代码段中,bike()
函数的工作是打印this.name
,这意味着它正在尝试打印当前执行上下文的(i.e.this object)
的name属性的值。
在上面的代码片段中,调用函数bike()
时,它会打印“ Ninja”,因为未指定执行上下文,因此默认情况下它是全局上下文,并且在全局上下文中存在一个变量名称,其值是“忍者”。
在进行obj1().bike()
调用的情况下,将打印“ Pulsar”,其背后的原因是函数bike()
的执行上下文为obj1
,因此this.name
变为obj1.name
。与obj2.bike()
调用相同,其中函数bike()
的执行上下文为obj2
。
“ this”的默认和隐式绑定
如果我们处于严格模式,则此关键字的默认值是不确定的,否则此关键字用作全局对象,称为此关键字的默认绑定。 (对于浏览器,默认为窗口对象。)
当我们将某个对象属性作为方法调用时,该对象成为该方法的该对象或执行上下文对象,这是此关键字的隐式绑定。
var obj1 = {
name: "Pulsar",
bike: function() {
console.log(this.name);
}
}
var obj2 = { name: "Gixxer", bike: obj1.bike };
var name = "Ninja";
var bike = obj1.bike;
bike(); // "Ninja"
obj1.bike(); // "Pulsar"
obj2.bike(); // "Gixxer"
在上面的代码片段中,函数调用bike()
是默认绑定的示例。 obj1.bike()
和obj2.bike()
是隐式绑定的示例。在这里,自行车功能被声明为obj1
的一部分,但是无论我们在executeobj2.bike()
时是什么,执行的上下文都是obj2
,因此obj2.name
会被打印出来。
重要的是要知道如何,何时何地调用该函数,而与声明函数的位置无关。
“ this”关键字的显式和固定绑定
如果我们将call和apply方法与调用函数一起使用,则这两个方法均将其第一个参数作为执行上下文。这就是这种约束力。
function bike() {
console.log(this.name);
}
var name = "Ninja";
var obj = { name: "Pulsar" }
bike(); // "Ninja"
bike.call(obj); // "Pulsar"
在上面的代码片段中,如果我们使用call()
方法调用功能自行车,并将执行上下文对象obj作为第一个参数,则obj被分配给该对象,并且打印出“ Pulsar”,该文本不过是{{1 }}。称为此关键字的显式绑定。
在固定装订或硬装订中
无论从何处以及如何调用此对象,我们都可以强制使该对象始终相同。
obj.name
根据上面的代码片段,var bike = function() {
console.log(this.name);
}
var name = "Ninja";
var obj1 = { name: "Pulsar" };
var obj2 = { name: "Gixxer" };
var originalBikeFun = bike;
bike = function() {
originalBikeFun.call(obj1);
};
bike(); // "Pulsar"
bike.call(obj2); // "Pulsar"
和bike()
都调用打印“ Pulsar”,除了bike.call(obj2)
之外什么都没有,这意味着功能自行车的执行上下文始终为obj1.name
并且是因为obj1
;这种绑定只是显式绑定的另一种形式,称为固定绑定。
答案 22 :(得分:0)
要正确理解“此”,必须了解上下文和范围以及它们之间的区别。
作用域:在javascript中,作用域与变量的可见性有关,作用域通过使用函数来实现。 (了解有关范围的更多信息)
上下文:上下文与对象有关。它是指功能所属的对象。当您使用JavaScript“ this”关键字时,它指向函数所属的对象。 例如,在函数内部,当您说:“ this.accoutNumber”时,是指属性“ accoutNumber”,该属性属于该函数所属的对象。
如果对象“ myObj”具有称为“ getMyName”的方法,则当在“ getMyName”内部使用JavaScript关键字“ this”时,它将引用“ myObj”。如果函数“ getMyName”是在全局范围内执行的,则“ this”是指窗口对象(严格模式下除外)。
现在让我们看一些示例:
<script>
console.log('What is this: '+this);
console.log(this);
</script>
根据您在窗口对象上下文内的输出,还可以看到窗口原型引用了该对象。
现在让我们尝试一个函数内部:
<script>
function myFunc(){
console.log('What is this: '+this);
console.log(this);
}
myFunc();
</script>
输出:
输出是相同的,因为我们在全局作用域中记录了“ this”变量,而在功能作用域中记录了该变量,我们没有更改上下文。在两种情况下,上下文都是相同的,与寡妇对象有关。
现在让我们创建自己的对象。在javascript中,您可以通过多种方式创建对象。
<script>
var firstName = "Nora";
var lastName = "Zaman";
var myObj = {
firstName:"Lord",
lastName:'Baron',
printNameGetContext:function(){
console.log(firstName + " "+lastName);
console.log(this.firstName +" "+this.lastName);
return this;
}
}
var context = myObj.printNameGetContext();
console.log(context);
</script>
因此,从上面的示例中,我们发现'this'关键字是指与myObj相关的新上下文,并且myObject也具有指向Object的原型链。
我们再举一个例子:
<body>
<button class="btn">Click Me</button>
<script>
function printMe(){
//Terminal2: this function declared inside window context so this function belongs to the window object.
console.log(this);
}
document.querySelector('.btn').addEventListener('click', function(){
//Terminal1: button context, this callback function belongs to DOM element
console.log(this);
printMe();
})
</script>
</body>
如果您无法理解上面的示例,请尝试使用我们自己的回调;
<script>
var myObj = {
firstName:"Lord",
lastName:'Baron',
printName:function(callback1, callback2){
//Attaching callback1 with this myObj context
this.callback1 = callback1;
this.callback1(this.firstName +" "+this.lastName)
//We did not attached callback2 with myObj so, it's reamin with window context by default
callback2();
/*
//test bellow codes
this.callback2 = callback2;
this.callback2();
*/
}
}
var callback2 = function (){
console.log(this);
}
myObj.printName(function(data){
console.log(data);
console.log(this);
}, callback2);
</script>
现在让我们了解一下范围,自我,IIFE和这种行为
var color = 'red'; // property of window
var obj = {
color:'blue', // property of window
printColor: function(){ // property of obj, attached with obj
var self = this;
console.log('In printColor -- this.color: '+this.color);
console.log('In printColor -- self.color: '+self.color);
(function(){ // decleard inside of printColor but not property of object, it will executed on window context.
console.log(this)
console.log('In IIFE -- this.color: '+this.color);
console.log('In IIFE -- self.color: '+self.color);
})();
function nestedFunc(){// decleard inside of printColor but not property of object, it will executed on window context.
console.log('nested fun -- this.color: '+this.color);
console.log('nested fun -- self.color: '+self.color);
}
nestedFunc(); // executed on window context
return nestedFunc;
}
};
obj.printColor()(); // returned function executed on window context
</script>
答案 23 :(得分:-1)
简单答案:
“此”关键字始终取决于调用的上下文。它们在下面提到。
使用新关键字调用了功能
如果使用NEW关键字调用该函数,则此函数将绑定到新创建的对象。
function Car(){
this.name="BMW";
}
const myCar=new Car();
myCar.name; // output "BMW"
在上面,它将绑定到“ myCar”对象
使用呼叫和应用方法明确调用功能。
在这种情况下,THIS将绑定到显式传递给函数的对象。
var obj1={"name":"bond"};
function printMessage(msg){
return msg+" "+this.name;
}
const message=printMessage.call(obj1,"my name is ");
console.log(message); //HERE THIS WILL BE BOUND TO obj1 WHICH WE PASSED EXPLICITLY. SAME FOR APPLY METHOD ALSO.
如果隐式调用了功能,则该功能将绑定到该对象上
var obj1={
"name":"bond",
getName: function () {
return this.name;
}
};
const newname=obj1.getName();
console.log(newname); //HERE THIS WILL BE BOUND TO obj1(WHITCHEVER OBJECT IS MENTIONED BEFORE THE DOT THIS WILL BE BOUND TO THAT)
在没有任何上下文的情况下调用功能,那么它将被限制在全球范围内
const util = {
name: 'Utility',
getName: function () {
return this.name;
};
const getName=util.getName;
const newName=getName();
console.log(newName); // IF THIS EXECUTED IN BROWSER THIS WILL BE BOUND TO WINDOW OBJECT. IF THIS EXECUTED IN SERVER THIS WILL BE BOUND TO GLOBAL OBJECT
在严格模式下将无法定义
function setName(name){
"use strict"
return this.name;
}
setName(); //WILL BE ERROR SAYING name IS UNDEFINED.