相信很多人都能正确地访问属性和访问变量,但对于一些特性的问题(如本文中的第2部分< 未定义的变量与未定义的属性的访问 >)可能就不知其所以然了,造成这种情况的原因就是:对于这些知识,只是会用,但不理解;
为了帮助大家深入理解JavaScript中标识符查找过程,现给出规则和应用示例如下:(若想更深入地理解JavaScript的各种特性,可以参考另一篇文章:《JavaScript的发现与理解》)
1.标识符查找
- 访问属性,查找的是原型链;
- 访问变量,查找的是作用域链;
作用链是一个栈,栈里保存的是作用域对象,栈的最顶端是当前作用域对象,栈的最底端是全局作用域对象;
作用域对象只有2种:
- 全局作用域对象;
- 函数作用域对象;
所以当通过属性调用的方式调用对象的方法时,该对象只会成this的值;不会成为它的方法(即:对象中属性值是函数的属性)的作用域链中的作用域对象,不过可以通过with操作符使对象成为它的方法的作用域链中的作用域对象;
2. 未定义的变量与未定义的属性的访问
假设以下代码在全局作用域下执行,且gby和dyx都从未定义过,则执行结果如下:
gby; //结果:报错:ReferenceError: Can't find variable: gby;
window.gby; //结果:undefined
window.dyx; //结果:undefined
所以:访问未定义的变量会报错,但访问未定义的属性不会报错,只是结果为undefined;
如果gby是全局变量,则gby 和 window.gby 访问的都是同一个变量,那为什么这两种访问方式的结果不一样呢?我认为原因如下:
访问变量时是通过搜索作用域链来查找变量的,而访问属性是通过搜索原型链来查找属性的,因为这两种访问方式的搜索方式不一样,所以导致了结果不一样;