我希望找到一个清晰的解释,“this”关键字的作用是什么,以及如何正确使用它。
它似乎表现得很奇怪,我不完全明白为什么。
this
如何工作,应该在什么情况下使用?
我希望找到一个清晰的解释,“this”关键字的作用是什么,以及如何正确使用它。
它似乎表现得很奇怪,我不完全明白为什么。
this
如何工作,应该在什么情况下使用?
this
Javascript:this
的值取决于函数的调用方式,而不是它创建的位置!this
的值由点号左侧的对象决定。(在全局空间中为window
)this
的值指向调用事件的DOM元素。new
关键字调用函数时,this
的值指向新创建的对象。call
、apply
、bind
函数来操作this
的值。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.
要正确理解“this”,必须了解上下文、范围和它们之间的区别。
范围:在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>
输出:
有道理吧?(阅读评论)
{{link1:}}
如果您难以理解上面的示例,让我们尝试使用自己的回调函数;
<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>
现在让我们了解作用域、Self、IIFE和THIS的行为方式
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>