大约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 的相关错误,从而快速地结束脚本。相关的常见错误消息有:
JS 开发人员可以理解这个笑话的讽刺:
function undefined() {
// problem solved
}
web前端开发学习Q-q-u-n: 767273102 ,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法(详细的前端项目实战教学视频)
为了降低此类错误的风险,必须理解生成undefined的情况。更重要的是抑制它的出现并阻止在应用程序中传播,从而提高代码的持久性。
让咱们详细讨论undefined 及其对代码安全性的影响。
JS 有6种基本类型
和一个单独的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
上述代码大致流程:
都会被定义为undefined。
ECMAScript规范定义了undefined 值的类型
Undefined type是其唯一值为undefined 值的类型。
在这个意义上,typeof undefined返回“undefined”字符串
typeof undefined === 'undefined'; // => true
当然typeof可以很好地验证变量是否包含undefined的值
let nothing;
typeof nothing === 'undefined'; // => true
尚未赋值(未初始化)的声明变量默认为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