Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

基本概念 #1

Open
vqun opened this issue Apr 2, 2015 · 1 comment
Open

基本概念 #1

vqun opened this issue Apr 2, 2015 · 1 comment

Comments

@vqun
Copy link
Owner

vqun commented Apr 2, 2015

#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,就很明显了。

@AlexCaesar
Copy link

hi, 方便加一下QQ或者微信不:4872232 对前端很感兴趣:)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants