Ionic V2和Cordova插件 - 未捕获的TypeError:无法设置null的属性'test'

Nei*_*off 1 javascript ionic-framework cordova-plugins ionic2

我正在使用Ionic v2和Phonegap条码扫描器插件.

当执行下面的scanBarcode()函数时,我收到错误:

Uncaught TypeError: Cannot set property 'test' of null
Run Code Online (Sandbox Code Playgroud)

this.test = result.text;
Run Code Online (Sandbox Code Playgroud)

码:

import {Page} from 'ionic-angular';


@Page({
  templateUrl: 'build/pages/scanBarcode/scanBarcode.html'
})
export class ScanBarcode {
  constructor() {
    this.test = "";
  }

  scanBarcode(){
    cordova.plugins.barcodeScanner.scan(
      function (result) {
        console.log(result.text);
        this.test = result.text;
        console.log("SB result" + test);
      },
      function (error) {
        alert("Scanning failed: " + error);
      }
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

第一个console.log没有错误,并显示正确的信息:

console.log(result.text);
Run Code Online (Sandbox Code Playgroud)

igo*_*ujo 6

你的代码的问题是你试图在scan方法的result函数中访问类的'this'指针.

要解决此问题,请执行以下操作:

scanBarcode(){

  //Create 'self' variable outside the scan function, assigning 'this' to it
  let self = this;

  cordova.plugins.barcodeScanner.scan(
    function (result) {
      console.log(result.text);
      //Use 'self' instead of 'this' to access 'test'
      self.test = result.text;
      console.log("SB result" + test);
    },
    function (error) {
      alert("Scanning failed: " + error);
    }
  )
}
Run Code Online (Sandbox Code Playgroud)

说明

当你调用.scan()函数时,你给它两个回调.你不能用'this'来完成你想要的东西,因为在Javascript中,'this'具有函数调用者的上下文.

通常,当您在回调中访问"this"时,它具有"窗口"上下文.那是因为当你(定义和)调用没有对象上下文的函数时,你实际上是在使用'window'上下文.例:

function fun(){ console.log('this = window; in here');
fun();
Run Code Online (Sandbox Code Playgroud)

实际发生的是:

window.fun = function() { /* ... */ }
window.fun(); 
Run Code Online (Sandbox Code Playgroud)

(有关这方面的更多信息,请阅读有关javascript基于原型的面向对象模型的信息)

在这种情况下,您将无法设置未定义错误的属性"test".但是,由于你的回调是由cordova插件直接调用的,我相信'this'根本没有上下文(尽管我不确定).

无论如何,由于没有使用类实例上下文调用回调,因此'this'不代表类的实例,因此没有'test'属性.

最后,由于回调是一个闭包,并且闭包记住了创建它的环境,因此回调知道'self'变量的存在.这就是为什么你可以在这种情况下使用它.