1.变量作用域
var a = 1; function test() { var a = 2; console.log(a); // 2 } test();
上方的函数作用域中声明并赋值了a,且在console之上,所以遵循就近原则输出a等于2。
var a = 1; function test2() { console.log(a); // undefined var a = 2; } test2();
上方的函数作用域中虽然声明并赋值了a,但位于console之下,a变量被提升,输出时已声明但尚未被赋值,所以输出“undefined”。
var a = 1; function test3() { console.log(a); // 1 a = 2; } test3();
上方的函数作用域中a被重新赋值,未被重新声明,且位于console之下,所以输出全局作用域中的a。
变量提升这个概念,只适用于声明变量的语句,而变量赋值的语句并不能被提前(如果执行语句可以随意调换顺序,其破坏性可想而知)
我们习惯将‘var a = 3’看做一条声明。其实这里两条语句的简写,‘var a’和‘a = 3’,并且其实这两条语句是两个不同类型的语句,是由两个不同的组件完成的。前一句是在编译阶段执行,后一句是在运行阶段执行
所以,不管’var a’写在哪里,都会在代码本身被执行之前处理。这一过程很像是代码的一个移动过程,所以被大家称为“变量提升”。
2.类型比较
var arr = [], arr2 = [1]; console.log(arr === arr2); // false
上方两个不同的数组比较,console为false。
var arr = [], arr2 = []; console.log(arr === arr2); // false
上方两个相同的数组比较,console为false。
原因:
因为两个单独的数组永不相等
var arr = [], arr2 = {}; console.log(typeof(arr) === typeof(arr2)); // true
上方利用typeof比较数组和对象,因为typeof获取NULL、数组、对象的类型都为object,所以console为true
var arr = []; console.log(arr instanceof Object); // true console.log(arr instanceof Array); // true
上方利用instanceof判断一个变量是否属于某个对象的实例,因为在JavaScript中数组也是对象的一种,所以两个console都为true。
3.this指向
移步本人博客
http://www.cnblogs.com/QianBoy/p/7599202.html
4.闭包问题
var elem = document.getElementsByTagName('div'); // 如果页面上有5个div for(var i = 0; i < elem.length; i++) { elem[i].onclick = function () { alert(i); // 总是5 }; }
上方是一个很常见闭包问题,点击任何div弹出的值总是5
var elem = document.getElementsByTagName('div'); // 如果页面上有5个div for(var i = 0; i < elem.length; i++) { (function (w) { elem[w].onclick = function () { alert(w); // 依次为0,1,2,3,4 }; })(i); }
结语
学习JavaScript是一个漫长的过程,不能一蹴而就。希望本文介绍的几点内容能够帮助学习JavaScript的同学更加深入的了解和掌握JavaScript的语法,少走弯路。