我有一个注册事件处理程序的构造函数:

函数MyConstructor(数据,传输){this.data=数据;transport.on('数据',函数(){警报(this.data);});}//模拟传输对象var传输={on:函数(事件,回调){setTimeout(回调,1000);}};//称为var obj=新MyConstructor('o',传输);

但是,我无法访问回调中创建的对象的数据属性。看起来这不是指创建的对象,而是指另一个对象。

我还尝试使用对象方法而不是匿名函数:

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', this.alert);
}

MyConstructor.prototype.alert = function() {
    alert(this.name);
};

但它表现出相同的问题。

如何访问正确的对象?


当前回答

你应该知道“this”关键字。

根据我的观点,你可以通过三种方式实现“这一点”(自身|箭头函数|绑定方法)

与其他语言相比,函数的this关键字在JavaScript中的表现稍有不同。

严格模式和非严格模式之间也有一些区别。

在大多数情况下,其值取决于函数的调用方式。

它不能在执行过程中通过赋值来设置,每次调用函数时可能会有所不同。

ES5引入了bind()方法来设置函数的值,

ES2015引入了箭头函数,这些函数不提供自己的绑定(它保留了封闭词汇上下文的值)。

方法1:Self-Self被用于维护对原始this的引用,即使上下文在变化。这是一种常用于事件处理程序(尤其是闭包)的技术。

参考:此

function MyConstructor(data, transport) {
    this.data = data;
    var self = this;
    transport.on('data', function () {
        alert(self.data);
    });
}

方法2:箭头函数-箭头函数表达式在语法上是正则函数表达式的一种紧凑的替代方法,尽管它本身没有与this、arguments、super或new.target关键字的绑定。

箭头函数表达式不适合作为方法,并且不能用作构造函数。

参考:箭头函数表达式

  function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data',()=> {
        alert(this.data);
    });
}

方法3:Bind-Bind()方法创建一个新函数,当调用该函数时,将其this关键字设置为所提供的值,并在调用新函数时提供的任何参数之前使用给定的参数序列。

引用:Function.pr原型.bind()

  function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data',(function() {
        alert(this.data);
    }).bind(this);

其他回答

其他一些人已经谈到了如何使用.bind()方法,但这里特别介绍了如果有人在让它们一起工作时遇到困难,如何将其与.then()一起使用:

someFunction()
.then(function(response) {
    //'this' wasn't accessible here before but now it is
}.bind(this))

如注释中所述,另一种方法是使用没有自己的“this”值的箭头函数

someFunction()
.then((response)=>{
    //'this' was always accessible here
})

以下是访问子上下文中的父上下文的几种方法-

您可以使用bind()函数。在另一个变量中存储对context/this的引用(参见下面的示例)。使用ES6箭头功能。改变代码、功能设计和架构——为此,您应该能够控制JavaScript中的设计模式。

1.使用bind()函数

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', ( function () {
        alert(this.data);
    }).bind(this) );
}
// Mock transport object
var transport = {
    on: function(event, callback) {
        setTimeout(callback, 1000);
    }
};
// called as
var obj = new MyConstructor('foo', transport);

如果您正在使用Undercore.js-http://underscorejs.org/#bind

transport.on('data', _.bind(function () {
    alert(this.data);
}, this));

2.在另一个变量中存储对context/this的引用

function MyConstructor(data, transport) {
  var self = this;
  this.data = data;
  transport.on('data', function() {
    alert(self.data);
  });
}

3.箭头功能

function MyConstructor(data, transport) {
  this.data = data;
  transport.on('data', () => {
    alert(this.data);
  });
}

我们不能将其绑定到setTimeout(),因为它总是使用全局对象(Window)执行。如果您想在回调函数中访问this上下文,那么通过对回调函数使用bind(),我们可以如下实现:

setTimeout(function(){
    this.methodName();
}.bind(this), 2000);

我遇到了Ngx折线图xAxisTickFormatting函数的问题,该函数是从HTML调用的,如下所示:[xAxisTikFormatting]=“xFormat”。

我无法从声明的函数访问组件的变量。这个解决方案帮助我解决了问题,找到了正确的答案。

不要像这样使用函数:

xFormat (value): string {
  return value.toString() + this.oneComponentVariable; //gives wrong result
}

使用此项:

 xFormat = (value) => {
   // console.log(this);
   // now you have access to your component variables
   return value + this.oneComponentVariable
 }

“上下文”的问题

术语“上下文”有时用于指代此引用的对象。它的使用是不合适的,因为它在语义上或技术上都不符合ECMAScript的this。

“上下文”是指围绕着某事物的环境,它增加了意义,或是一些前后信息赋予了额外的意义。ECMAScript中使用术语“上下文”来指代执行上下文,它是一些执行代码范围内的所有参数、范围和内容。

如ECMA-262第10.4.2节所示:

将ThisBinding设置为与调用执行上下文

这清楚地表明这是执行上下文的一部分。

执行上下文提供为正在执行的代码添加意义的周围信息。它包含了比thisBinding更多的信息。

它的价值不是“上下文”。它只是执行上下文的一部分。它本质上是一个局部变量,可以通过对任何对象的调用,在严格模式下,设置为任何值。