我刚刚在JavaScript中遇到了一个有趣的情况。我有一个类,它的方法使用对象文字表示法定义了几个对象。在这些对象中,使用了this指针。从程序的行为中,我推断this指针指向调用方法的类,而不是由文字创建的对象。
这似乎是随意的,尽管这是我所期望的工作方式。这是已定义的行为吗?它跨浏览器安全吗?是否有任何潜在的原因,为什么它会超出“规格说明”(例如,这是一些更广泛的设计决策/哲学的结果)?简化后的代码示例:
// inside class definition, itself an object literal, we have this function:
onRender: function() {
this.menuItems = this.menuItems.concat([
{
text: 'Group by Module',
rptletdiv: this
},
{
text: 'Group by Status',
rptletdiv: this
}]);
// etc
}
这里所有的答案都是非常有用的,但我仍然很难弄清楚这一点在我的情况下是什么,这涉及到对象解构。所以我想用简化版的代码再加一个答案,
let testThis = {
x: 12,
y: 20,
add({ a, b, c }) {
let d = a + b + c()
console.log(d)
},
test() {
//the result is NaN
this.add({
a: this.x,
b: this.y,
c: () => {
//this here is testThis, NOT the object literal here
return this.a + this.b
},
})
},
test2() {
//64 as expected
this.add({
a: this.x,
b: this.y,
c: () => {
return this.x + this.y
},
})
},
test3() {
//NaN
this.add({
a: this.x,
b: this.y,
c: function () {
//this here is the global object
return this.x + this.y
},
})
},
}
正如这里解释的Javascript -解构对象- 'this'设置为全局或未定义,而不是object,它实际上与对象解构无关,而是如何调用c(),但在这里不容易通过它看到。
MDN说“箭头函数表达式最适合于非方法函数”,但箭头函数在这里也适用。
我找到了一个关于ECMAScript的很好的教程
这个值是一个与执行相关的特殊对象
上下文。因此,它可以被命名为上下文对象(即一个对象)
对象,在其中上下文中激活执行上下文)。
任何对象都可以用作上下文的这个值。
此值是执行上下文的属性,但不是
属性。
这个特性非常重要,因为与变量相反,这个值从不参与标识符解析过程。也就是说,当在代码中访问this时,它的值直接从执行上下文中获取,而不需要任何作用域链查找。this的值在进入上下文时只确定一次。
在全局上下文中,this值是全局对象本身(这意味着,这里的this值等于变量对象)。
对于函数上下文,这个值在每个单独的函数调用中都可能是不同的
参考Javascript-the-core和第3-this章
这在JS中:
有三种不同意义的函数类型。最好通过例子来解释:
构造函数
//在构造函数中this指向新创建的对象
//每个函数都可以是JavaScript的构造函数。
函数的狗(颜色){
这一点。颜色=颜色;
}
//通过在函数调用前放置new来调用构造函数
const myDog = new Dog('red');
// logs狗有红色
console.log('狗有颜色' + myDog.color);
正常的函数或方法
// Browswer example:
console.log(this === window) // true
function myFn(){
console.log(this === window)
}
myFn(); // logs true
// The value of this depends on the context object.
// In this case the context from where the function is called is global.
// For the global context in the browser the context object is window.
const myObj = {fn: myFn}
myObj.fn() // logs false
// In this case the context from where the function is called is myObj.
// Therefore, false is logged.
myObj.fn2 = function myFn(){
console.log(this === myObj)
}
myObj.fn2() // logs true
// In this case the context from where the function is called is myObj.
// Therefore, true is logged.
事件监听器
在事件处理程序的函数中,this将引用检测到事件的DOM元素。请看这个问题:在事件处理程序中使用这个