JS基础[1]

原文链接https://github.com/vqun/blog/issues/1

  1. 基本概念
    ===
    1.1 变量

ECMA变量是松散型的,爱保存啥类型的数据都行。变量申明使用的是var,当然也可以不用。使用var,申明局部变量,不使用申明全局变量。不使用var是为JS界所鄙视的,所以,建议申明变量时,带上var。

function f(){
  var x = 1; // x是局部变量,只在f
  y = 2; // y是全局变量
}
f();
alert(x); // 报错
alert(y); // 2(当然,前提是你注释了上一句话)

变量有三个阶段:申明、赋值和使用。

申明和赋值是两个完全不同的概念,解释器对于这两个阶段也是完全不同的,申明是在代码期(写代码时期,业界喜欢叫预编译还是啥的),赋值是在运行期。

var a; // 这是申明
a = 1; // 这是赋值

var b = 2; // 这句话,在代码期,解释器只做了var b;在运行期,做了b = 2

这也牵扯一下JS界都喜欢问的一个题:

alert(c); // undefined
var c = 3;

之所以是undefined,涉及到了所谓的“Hoisting”(变量提升)。变量提升里说了,变量申明会被提前,于是乎上述代码被等同于:

var c;
alert(c);
c = 3;

这其实是因为申明和赋值在两个不同阶段。
1.2 区分大小写


这个你懂的
1.3 标识符


说一点,一般认为的标识符,是非保留字,以_、$、字母开头。实际上,还可以是Unicode、ASIIC,因此,连中文都可以直接作为标签符的,例如:

var 你好 = 1;
alert(你好);
var \u7788 = 2;
alert(\u7788);

上面两个都可以正常运行。当然,这种用写法在实际编程里是不推荐的,只是曾经有吃饱没事干的面试官出过这种面试题,算是普及一下
1.4 注释


两种注释风格,和C/C++类似,单行注释和多行注释:

// 单选注释
/*
 * 多行注释
 */

1.5 分号

关于分号,编程习惯就是在语句的结尾加分号。当然,如果你想装逼,好好看ECMA262,里面告诉你了什么时候要加分号,什么时候不用。
1.6 关键字和保留字


曾经有人问,关键字和保留字有什么区别。其实,从实际角度讲呢,因为你都不会去当成标识符,所以没区别;概念角度讲呢,关键字是真不能用(加了引号可以),保留字呢,目前可用,以后估计就不能用了。
1.7 数据类型


五种基本类型+一种引用类型。五种基本类型:Undefined、Null、Number、String、Boolean,一种引用类型:Object。

typeof:这是一个比较让人无语的操作符,以致于业界都不喜欢用它来判断数据类型。其实,让人无语,主要是因为对null,array使用typeof时,返回的不是期望的“null”和“array”,而是“object”。这个其实没什么,从理解角度讲,是挺合理的,null本身就是代表的空对象,array本身在JS里根本没这个类型。当然,Number、Boolean等直接new出来的,typeof结果也是“object”。

1.8 操作符

操作符都有返回值。合理利用这个返回值,可以提升你的代码逼格。比如,一般人都这么写:

var obj = {
  "a": {
    "name": "hello",
    "value": 1
  },
  "b": {
    "name": "world",
    "value": 2
  }
}, tmp, n, ret = {};
for(var k in obj){
  tmp = obj[k];
  n = tmp.name;
  !!n && ret[n] = tmp;
}

博主喜欢这么装逼:

var obj = {
  "a": {
    "name": "hello",
    "value": 1
  },
  "b": {
    "name": "world",
    "value": 2
  }
}, tmp, n, ret = {};
for(var k in obj)
  !!(n = (tmp = obj[k]).name) && ret[n] = tmp;

有木有觉得逼格一样子提升了好几个档次,连for循环的花括号都省了。。。其实,我会告诉你,只是因为后者的性能更高,所以我才用的。
1.9 语句


语句包括:if、do-while、while、for、for-in、label、break和continue、with以及switch。除了with,其他的都很简单,只要记得JS没有块作用域就可以了。

关于with,“with会在原作用域链里插入新的作用域,影响性能”这句话是JS界里流行的几句话[1]之一。确实,因为作用域链的问题,with存在性能问题,不过,很多模版引擎却用了with来实现,如underscoreJs内置的template,其“编译”完之后的代码里,就用了with来遍历对象,以达到在模版里直接使用对象的属性名。

[1]JS界里流行的几句话:

1. 变量申明会被提到最前面
2. eval是邪恶的
3. with会在原作用域链里插入新的作用域,影响性能

1.10 函数

函数定义有三种方式:函数申明、函数表达式和构造函数。

// 函数申明
function f(){
  console.log("declaration");
}
// 函数表达式
var f = function(){
  console.log("expression");
}
// 构造函数
var f = new Function("console.log('constructor')");

函数申明会在预编译阶段就确定,表达式和构造函数是在运行时确定。这再牵扯一下业界面试题喜欢玩的一个题:

alert(a); // 输出那个function
var a = 1;
alert(a); // 输出1
function a(){
  console.log("function")
}
alert(a); // 输出1

上述代码中,由于在预编译时,function a(){...}确定了,因此,在运行时,第一个alert就将这个函数申明alert出了,而第二个第三个alert,就很明显了。

推荐阅读更多精彩内容

  • js的历史 在上个世纪的1995年,当时的网景公司正凭借其Navigator浏览器成为Web时代开启时最著名的第一...
    LaBaby_阅读 41评论 0 2
  • 近期开始接触学习extjs框架。该框架是基于JavaScript的。为了更好地理解学习extjs,必然需要先对Ja...
    六尺帐篷阅读 461评论 2 13
  • 第一章: JS简介 从当初简单的语言,变成了现在能够处理复杂计算和交互,拥有闭包、匿名函数, 甚至元编程等...
    LaBaby_阅读 205评论 0 4
  • 《ijs》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 10...
    叶染柒丶阅读 1,460评论 0 5
  • 我不是一个安静的人 这我很肯定 但我常常装成 一个安静的人 总有人高谈阔论 总有人 我不得不 安静得更大点声 像根...
    疯界阅读 31评论 0 1