今天主要是来讲讲关于js最底层的基础知识,把握每个细节,做一个真正了解前端的前端。
主要涵盖属性、变量,提升,比较运算符,块, 请君侧耳听
一.属性
1.通过.
来访问对象的属性
var luke = {
jedi: true,
age: 28
};
// bad
var isJedi = luke['jedi'];
// good
var isJedi = luke.jedi;
2.当通过变量访问属性时使用中括号[]
var luke = {
jedi: true,
age: 28
};
function getProp(prop) {
return luke[prop];
}
var isJedi = getProp('jedi');
2.变量
1.使用 var
来声明变量,不这么做将导致产生全局变量。我们要避免污染全局命名空间。
// bad
superPower = new SuperPower();
// good
var superPower = new SuperPower();
2.使用 var
声明每一个变量。 这样做的好处是增加新变量将变的更加容易,而且你永远不用再担心调换错 ;
和,
// bad
var items = getItems(),
goSportsTeam = true,
dragonball = 'z';
// bad
var items = getItems(),
goSportsTeam = true;
dragonball = 'z';
// good
var items = getItems();
var goSportsTeam = true;
var dragonball = 'z';
3.最后再声明未赋值的变量。当你需要引用前面的变量赋值时这将变的很有用
// bad
var i, len, dragonball,
items = getItems(),
goSportsTeam = true;
// bad
var i;
var items = getItems();
var dragonball;
var goSportsTeam = true;
var len;
// good
var items = getItems();
var goSportsTeam = true;
var dragonball;
var length;
var i;
4.在作用域顶部声明变量。这将帮你避免变量声明提升相关的问题
// bad
function () {
test();
console.log('doing stuff..');
//..other stuff..
var name = getName();
if (name === 'test') {
return false;
}
return name;
}
// good
function () {
var name = getName();
test();
console.log('doing stuff..');
//..other stuff..
if (name === 'test') {
return false;
}
return name;
}
// bad - 不必要的函数调用
function () {
var name = getName();
if (!arguments.length) {
return false;
}
this.setFirstName(name);
return true;
}
// good
function () {
var name;
if (!arguments.length) {
return false;
}
name = getName();
this.setFirstName(name);
return true;
}
3.提升
1.变量声明会提升至作用域顶部,但赋值不会
// 我们知道这样不能正常工作(假设这里没有名为 notDefined 的全局变量)
function example() {
console.log(notDefined); // => throws a ReferenceError
}
// 但由于变量声明提升的原因,在一个变量引用后再创建它的变量声明将可以正常工作。
// 注:变量赋值为 `true` 不会提升。
function example() {
console.log(declaredButNotAssigned); // => undefined
var declaredButNotAssigned = true;
}
// 解释器会把变量声明提升到作用域顶部,意味着我们的例子将被重写成:
function example() {
var declaredButNotAssigned;
console.log(declaredButNotAssigned); // => undefined
declaredButNotAssigned = true;
}
2.匿名函数表达式会提升它们的变量名,但不会提升函数的赋值
function example() {
console.log(anonymous); // => undefined
anonymous(); // => TypeError anonymous is not a function
var anonymous = function () {
console.log('anonymous function expression');
};
}
3.命名函数表达式会提升变量名,但不会提升函数名或函数体
function example() {
console.log(named); // => undefined
named(); // => TypeError named is not a function
superPower(); // => ReferenceError superPower is not defined
var named = function superPower() {
console.log('Flying');
};
}
// 当函数名跟变量名一样时,表现也是如此。
function example() {
console.log(named); // => undefined
named(); // => TypeError named is not a function
var named = function named() {
console.log('named');
}
}
4.函数声明提升它们的名字和函数体
function example() {
superPower(); // => Flying
function superPower() {
console.log('Flying');
}
}
4.比较运算符
1.优先使用 === 和 !== 而不是 == 和 !=
2.条件表达式例如 if 语句通过抽象方法 ToBoolean 强制计算它们的表达式并且总是遵守下面的规则:
- 对象 被计算为 true
- Undefined,Null 被计算为 false
- 布尔值 被计算为 布尔的值
- 数字 如果是 0 或 NaN 被计算为 false,否则为 true
- 字符串 如果是空字符串 ’ ’ 被计算为 false,否则为 true
if ([0]) {
// true
// 一个数组就是一个对象,对象被计算为 true
}
3.使用快捷方式
// bad
if (name !== '') {
// ...stuff...
}
// good
if (name) {
// ...stuff...
}
// bad
if (collection.length > 0) {
// ...stuff...
}
// good
if (collection.length) {
// ...stuff...
}
5.块
1.使用大括号包裹所有的多行代码块
// bad
if (test)
return false;
// good
if (test) return false;
// good
if (test) {
return false;
}
// bad
function () { return false; }
// good
function () {
return false;
}
2.如果通过 if 和 else 使用多行代码块,把 else 放在 if 代码块关闭括号的同一行
// bad
if (test) {
thing1();
thing2();
}
else {
thing3();
}
// good
if (test) {
thing1();
thing2();
} else {
thing3();
}