如何确保用户输入的数据是 JavaScript 中的特定数据类型?

问题描述

我一直在用 JavaScript 进行一些基本的表单验证。目前,我有一个简单的 HTML 表单,它有三个输入字段 - 两个需要数字输入,一个需要字符串输入。但是,我正在努力实现这一点。

const displayMessage = function (message) {
  document.querySelector(".message").textContent = message;
};

const displayOtherMessage = function (message) {
  document.querySelector(".message1").textContent = message;
};

document.querySelector(".check").addEventListener("click",function () {
  const height = Number(document.querySelector(".height").value);
  const weight = Number(document.querySelector(".weight").value);
  const name = String(document.querySelector(".name").value);
  if (!height && !weight && !name) {
    displayMessage("Please enter a height,a weight and a name.");
  } else if (!height || !weight || !name) {
    displayMessage("Please enter a height,a weight and a name.");
  } else if (height && weight && name) {
    if (
      typeof weight !== "number" ||
      typeof height !== "number" ||
      typeof name !== "string"
    ) {
      displayOtherMessage(
        "Height must be a number,weight must be a number and name must be a string."
      );
    }
    displayMessage("");
    alert(
      `Thank you,${name}! You said you weigh ${weight} kilograms and are ${height} metres tall.`
    );
  }
});

这是我正在努力解决的问题:

 if (
      typeof weight !== "number" ||
      typeof height !== "number" ||
      typeof name !== "string"
    ) {
      displayOtherMessage(
        "Height must be a number,weight must be a number and name must be a string."
      );
    }

当我尝试在第二个输入字段中提交“John”时,会显示 displayMessage。我如何才能改为显示 displayOtherMessage?

此处为 HTML:

https://pastebin.com/E5Pm6Dku

解决方法

Number() 总是返回一个 number 并且 String() 总是返回一个字符串,所以那些 typeof 检查不会像你希望的那样做任何事情。

如果传递给 Number() 的字符串是一个无效数字,它将返回 NaN。所以你可以试试 isNaN(weight) 而不是 typeof

顺便说一句,在 Node.js 或浏览器控制台中,你可以直接尝试这种东西,比如 do:

> var height = Number("john")
> height
NaN
> typeof height
"number"
> isNaN(height)
true

也尝试使用您希望有效的值(例如 "10" 或其他)。

,

您的代码在检查中有点多余。例如,一个 describe('EmployeesStateService',() => { let store: Store; // Stub function response object that I will mutate in different tests. let queryResponse: QueryResponseDto = {}; let employeesServiceStub = { // Ensure that the stubbed function returns the mutatable object. // NOTE: This function is supposed to be an async function,so // the queryResponse object must be returned by the of() function // which is part of rxjs. If your function is not supposed to be async // then no need to pass it to the of() function from rxjs here. // Thank you again Mark! getEmployeesListQuery: jest.fn((skip,take) => of(queryResponse)) }; beforeEach(() => { TestBed.configureTestingModule({ imports: [ HttpClientTestingModule,NgxsModule.forRoot([EmployeesState]) ],providers: [ // Correctly use the useFactory option. { provide: EmployeesService,useFactory: () => employeesServiceStub } ] }); store = TestBed.inject(Store); TestBed.inject(EmployeesService); }); it('gets a list of employees',async () => { // Here I mutate the response object that the stubbed service will return queryResponse = { // ... }; await store.dispatch(new GetEmployeesList()).toPromise(); const list = store.selectSnapshot(state => state.employees.employeesList); expect(list).toStrictEqual([]); }); }); 值总是一个字符串,所以不需要检查它的类型,只要它不是空的。此外,您应该更具体地说明您需要用户做什么(哪个输入不正确)。你可以把它简化成这样:

<input>

https://jsfiddle.net/1L5qjg2o/3/

此外,请考虑对您的输入使用 const displayMessage = function (message) { document.querySelector(".message").textContent = message; }; document.querySelector(".check").addEventListener("click",function () { let height = document.querySelector(".height").value,name = document.querySelector(".name").value,weight = document.querySelector(".weight").value; if (!name) { displayMessage("Please enter a name."); } else if (!height || isNaN(Number(height))) { displayMessage("Height must be a number."); } else if (!weight || isNaN(Number(weight))) { displayMessage("Weight must be a number."); } else { displayMessage(`Thank you,${name}! You said you weigh ${weight} kilograms and are ${height} metres tall.` ); } }); 事件来执行这些检查。在我看来,如果您在用户输入时进行验证和更正,而不是等到他们最后提交所有内容然后不得不倒退时,那么用户体验会好得多。