易于人编写、易于人读是企业应用编程语言的终极追求。从js的发展你会发现,越来越多的语法糖,越来越“java”化,extend关键字等,都是在向一个通用的语法、词汇发展。我们会越来越不必关心某个表达式的具体实现,比如分析一个es5的表达式,var a = 10,js解释器先将当前作用域下所有的var声明的变量都定义出来,在js运行环境的内存中先构造了“变量a”这个对象,然后才是a=10的赋值操作,这个知识在编写代码或读代码的过程至为重要,否则你不会理解以下代码的结果。
doSomething();
function doSomething(){
console.log(a);
}
var a = 10;
没人会这么写代码,只有考题会这么出。但是有一些意料之外的bug正是由于这些机制的错误使用造成的。es6和之后的js,会越来越消灭这些机制,使程序员的门槛越来越低,你不必去理解什么原型链、作用域链,只要会点英语,有点逻辑思考能力,会if else,就能写代码了,这是趋势,拉低成为程序员的门槛,让更多的人成为程序员,让更多人替他们打工,就是他们的目的。es5也将会像汇编语言一样,逐渐地被“高级语言”替代。但是会汇编的人,一定比不会的人更理解程序的运行,同样,会es5的人,一定会更理解es6以至更以后的js规范。
我个人猜测,es5的许多奇怪的地方,正是为了提高js解释器解释效率,以提高js在浏览器的运行效率才出现的。比如原型链,作用域链,es5没有"extend"关键字,要实现继承要靠原型链。if语句不会生成一个作用域,for语句也不会生成一个作用域,比如
if(true){
var a = 1;
}
console.log(a); // 1
在java里变量a是取不到的。
function会生成一个作用域,比如:
function b(){
var a = 1;
}
b();
console.log(a); // 会报错
主流浏览器对es6的支持仍不到100%,更不用说更新的js标准,所以有babel这样的”预编译“器,将es6及更新的js标准的代码编译成es5代码。如果新一代浏览器能完全解释执行es6代码,并且运行机制完全不参考es5的,那么学习es5的“性价比”就很低了(性价比低,说明他还有“性能”,还有一点价值)。
我们写extjs,是用es5的,所以有必要了解一些,至少是一些皮毛(因为我们用extjs,很多复杂的东西我们不用写,写好if else,斟酌好变量命名就够了)。作用域链和原型链相关的,有兴趣的可以网上搜搜。
变量声明
var a;
a=10;
a=10;
var a;
a=10;
if(false){
var a;
}
以上三种写法等价。在一个作用域里,不管在哪声明变量,声明这个操作都会最先被解释。
函数声明提升
a();
function a(){
console.log(a);
}
这个和变量声明类似,不管在哪声明function,都会最先被解释。
虽然哪里声明变量、函数都行,代码都能运行,但是我们应遵守就近原则,哪用哪定义。像那种开头定义一坨变量,有的却在代码最末尾的地方才有用处,这是典型的墨守成规、刻舟求剑,这样写的人知道有命名提升这个事,就恪守这个规则,反而忽视了大原则,即代码应易理解。
if判断
var b = '';
console.log(!!b);
var c;
console.log(!!c);
var d = 0;
console.log(!!d);
var e = null;
console.log(!!e);
所以,在如下判断的时候,if(a!=undefined && a!='')
的时候,直接写if(a)
就好。但是在判断数字变量是否有值的时候要注意,因为0
转成bool也是false
,所以可以这样,if(a || a===0)
。
网友评论