web前端入门到实战:处理 JS中 undefined 的 7 个技巧

大约8年前,开始学习JS时,遇到了一个奇怪的情况,既存在undefined 的值,也存在表示空值的null。它们之间的明显区别是什么?它们似乎都定义了空值,而且,比较null == undefined的计算结果为true。

大多数现代语言,如Ruby、Python或Java都有一个空值(nil或null),这似乎是一种合理的方式。

对于JavaScript,解释器在访问尚未初始化的变量或对象属性时返回undefined。例如:

let company;
company;    // => undefined
let person = { name: 'John Smith' };
person.age; // => undefined

另一方面,null表示缺少的对象引用,JS本身不会将变量或对象属性设置为null。

一些原生方法,比如String.prototype.match(),可以返回null来表示丢失的对象。看看下面的示例:

let array = null;  
array;                // => null
let movie = { name: 'Starship Troopers',  musicBy: null };
movie.musicBy;        // => null
'abc'.match(/[0-9]/); // => null 

由于 JS 的宽容特性,开发人员很容易访问未初始化的值,我也犯了这样的错误。

通常,这种危险的操作会生成undefined 的相关错误,从而快速地结束脚本。相关的常见错误消息有:

  • TypeError: ‘undefined’ is not a function
  • TypeError: Cannot read property ‘’ of undefined
  • type errors

JS 开发人员可以理解这个笑话的讽刺:

function undefined() {
  // problem solved
}
web前端开发学习Q-q-u-n: 767273102 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法(详细的前端项目实战教学视频)

为了降低此类错误的风险,必须理解生成undefined的情况。更重要的是抑制它的出现并阻止在应用程序中传播,从而提高代码的持久性。

让咱们详细讨论undefined 及其对代码安全性的影响。

undefined 是什么鬼

JS 有6种基本类型

  • Boolean: true 或 false
  • Number: 1, 6.7, 0xFF
  • String: “Gorilla and banana”
  • Symbol: Symbol(“name”) (starting ES2015)
  • Null: null
  • Undefined: undefined.

和一个单独的Object 类型:{name: “Dmitri”}, [“apple”, “orange”]。

根据ECMAScript规范,从6种原始类型中,undefined是一个特殊的值,它有自己的Undefined类型。

未为变量赋值时默认值为undefined。

该标准明确定义,当访问未初始化的变量、不存在的对象属性、不存在的数组元素等时,将接收到一个undefined 的值。例如

let number;
number;     // => undefined

let movie = { name: 'Interstellar' };
movie.year; // => undefined

let movies = ['Interstellar', 'Alexander'];
movies[3];  // => undefined

上述代码大致流程:

  • 未初始化的变量number
  • 一个不存在的对象属性movie.year
  • 或者不存在数组元素movies[3]

都会被定义为undefined。

ECMAScript规范定义了undefined 值的类型

Undefined type是其唯一值为undefined 值的类型。

在这个意义上,typeof undefined返回“undefined”字符串


typeof undefined === 'undefined'; // => true    

当然typeof可以很好地验证变量是否包含undefined的值


let nothing;
typeof nothing === 'undefined';   // => true  

创建未定义的常见场景

2.1未初始化变量

尚未赋值(未初始化)的声明变量默认为undefined。


let myVariable;
myVariable; // => undefined    

myVariable已声明,但尚未赋值,默认值为undefined。

解决未初始化变量问题的有效方法是尽可能分配初始值。 变量在未初始化状态中越少越好。 理想情况下,你可以在声明const myVariable ='Initial value’之后立即指定一个值,但这并不总是可行的。

技巧1:使用 let 和 const 来代替 var

在我看来,ES6 最好的特性之一是使用const和let声明变量的新方法。const和let具有块作用域(与旧的函数作用域var相反),在声明行之前都存在于暂时性死区。

当变量一次性且永久地接收到一个值时,建议使用const声明,它创建一个不可变的绑定。

const的一个很好的特性是必须为变量const myVariable ='initial’分配一个初始值。 变量未暴露给未初始化状态,并且访问undefined是不可能的。

以下示例检查验证一个单词是否是回文的函数:


function isPalindrome(word) {
  const length = word.length;
  const half = Math.floor(length / 2);
  for (let index = 0; index < half; index++) {
    if (word[index] !== word[length - index - 1]) {
      return false;
    }
  }
  return true;
}
isPalindrome('madam'); // => true
isPalindrome('hello'); // => false    
web前端开发学习Q-q-u-n: 767273102 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法(详细的前端项目实战教学视频)

length 和 half 变量被赋值一次。将它们声明为const似乎是合理的,因为这些变量不会改变。

如果需要重新绑定变量(即多次赋值),请应用let声明。只要可能,立即为它赋一个初值,例如,let index = 0。

那么使用 var 声明呢,相对于ES6,建议是完全停止使用它。

var 声明的变量提会被提升到整个函数作用域顶部。可以在函数作用域末尾的某个地方声明v

你可能感兴趣的:(JavaScript,前端,web前端,前端开发,前端教程)