语法与数据类型
语法
var\let\const
用 var
或 let
语句声明的变量,如果没有赋初始值,则其值为 undefined。如果访问一个未声明的变量会导致抛出 ReferenceError 异常:
undefined
值在布尔类型环境中会被当作false
- 数值类型环境中
undefined
值会被转换为NaN
- 当你对一个 null 变量求值时,空值
null
在数值类型环境中会被当作 0 来对待
变量提升
一个函数中所有的
var
语句应尽可能地放在接近函数顶部的地方。
- JavaScript 变量的另一个不同寻常的地方是,你可以先使用变量稍后再声明变量而不会引发异常。这一概念称为变量提升;JavaScript 变量感觉上是被“提升”或移到了函数或语句的最前面。但是,提升后的变量将返回 undefined 值。因此在使用或引用某个变量之后进行声明和初始化操作,这个被提升的变量仍将返回 undefined 值。
- 在 ECMAScript 6 中,
let
和const
同样会被提升变量到代码块的顶部但是不会被赋予初始值。在变量声明之前引用这个变量,将抛出引用错误(ReferenceError)。这个变量将从代码块一开始的时候就处在一个“暂时性死区”,直到这个变量被声明为止。- 对于函数来说,只有函数声明会被提升到顶部,而函数表达式不会被提升。
/** * 例子 2 */ // will return a value of undefined var myvar = "my value"; (function () { console.log(myvar); // undefined var myvar = "local value"; })(); ------------------------------------------------------- console.log(x); // ReferenceError let x = 3; ---------------------------------------------------------- /* 函数声明 */ foo(); // "bar" function foo() { console.log("bar"); } /* 函数表达式 */ baz(); // 类型错误:baz 不是一个函数 var baz = function () { console.log("bar2"); };
常量
对象属性被赋值为常量是不受保护的,所以下面的语句执行时不会产生错误。
const MY_OBJECT = { key: "value" };
MY_OBJECT.key = "otherValue";
同样的,数组的被定义为常量也是不受保护的,所以下面的语句执行时也不会产生错误。
const MY_ARRAY = ["HTML", "CSS"];
MY_ARRAY.push("JAVASCRIPT");
console.log(MY_ARRAY); //logs ['HTML','CSS','JAVASCRIPT'];
全局变量
实际上,全局变量是全局对象的属性。在网页中,(译注:缺省的)全局对象是 window ,所以你可以用形如
window.
variable
的语法来设置和访问全局变量。常量
数据类型
- 七种基本数据类型:
- 布尔值(Boolean),有 2 个值分别是:
true
和false
。- null,一个表明 null 值的特殊关键字。JavaScript 是大小写敏感的,因此
null
与Null
、NULL
或变体完全不同。- undefined,和 null 一样是一个特殊的关键字undefined 表示变量未赋值时的属性。
- 数字(Number),整数或浮点数,例如:
42
或者3.14159
。- 任意精度的整数(BigInt),可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。
- 字符串(String),字符串是一串表示文本值的字符序列,例如:
"Howdy"
。- 代表(Symbol,在 ECMAScript 6 中新添加的类型)。一种实例是唯一且不可改变的数据类型。
- 以及对象(Object)。
对象属性名字可以是任意字符串,包括空串。如果对象属性名字不是合法的 javascript 标识符,它必须用引号包裹。
const unusualPropertyNames = { '': '空字符串', '!': '砰!' } console.log(unusualPropertyNames.''); // SyntaxError: Unexpected string console.log(unusualPropertyNames.!); // SyntaxError: Unexpected token ! ----------------------------------------------------------------------- console.log(unusualPropertyNames[""]); // 空字符串 console.log(unusualPropertyNames["!"]); // 砰!
!!!核心基础:1.访问对象属性foo['var']最稳妥 2.字符串插值"${var}"
//访问对象属性 var foo = { a: "alpha", 2: "two" }; console.log(foo.a); // alpha console.log(foo[2]); // two //console.log(foo.2); // SyntaxError: missing ) after argument list //console.log(foo[a]); // ReferenceError: a is not defined console.log(foo["a"]); // alpha console.log(foo["2"]); // two ---------------------------------------------------------------------------- //字符串插值"${var}" var name = "Bob", time = "today"; `Hello ${name}, how are you ${time}?`;
数字-》字符串:“+”
x = "The answer is " + 42; // "The answer is 42" y = 42 + " is the answer"; // "42 is the answer"
字符串-》数字:parseInt()、parseFloat()
parseInt
方法只能返回整数,所以使用它会丢失小数部分。另外,调用 parseInt 时最好总是带上进制(radix)参数,这个参数用于指定使用哪一种进制。x = "The answer is " + 42; // "The answer is 42" y = 42 + " is the answer"; // "42 is the answer"
进制
整数可以用十进制(基数为 10)、十六进制(基数为 16)、八进制(基数为 8)以及二进制(基数为 2)表示。
- 十进制整数字面量由一串数字序列组成,且没有前缀 0。
- 八进制的整数以 0(或 0O、0o)开头,只能包括数字 0-7。
- 十六进制整数以 0x(或 0X)开头,可以包含数字(0-9)和字母 a~f 或 A~F。
- 二进制整数以 0b(或 0B)开头,只能包含数字 0 和 1。
控制语句与错误处理
throw语句
throw "Error2"; // String type
throw 42; // Number type
throw true; // Boolean type
throw {
toString: function () {
return "I'm an object!";
},
};
------------------------------------------
//可以在抛出异常时声明一个对象。那你就可以在 catch 块中查询到对象的属性。
// Create an object type UserException
function UserException(message) {
this.message = message;
this.name = "UserException";
}
// Make the exception convert to a pretty string when used as
// a string (e.g. by the error console)
UserException.prototype.toString = function () {
return this.name + ': "' + this.message + '"';
};
// Create an instance of the object type and throw it
throw new UserException("Value too high");
try....catch...finally
换句话说,如果你在 try 代码块中的代码如果没有执行成功,那么你希望将执行流程转入 catch 代码块。如果 try 代码块没有抛出异常,catch 代码块就会被跳过。
finally
块无论是否抛出异常都会执行。如果抛出了一个异常,就算没有异常处理,finally
块里的语句也会执行。
执行顺序
function f() {
try {
console.log(0);
throw "bogus";
} catch (e) {
console.log(1);
return true; // this return statement is suspended
// until finally block has completed
console.log(2); // not reachable
} finally {
console.log(3);
return false; // overwrites the previous "return"
console.log(4); // not reachable
}
// "return false" is executed now
console.log(5); // not reachable
}
f(); // console 0, 1, 3; returns false
----------------------------------------------------------------------
function f() {
try {
throw "bogus";
} catch (e) {
console.log('caught inner "bogus"');
throw e; // this throw statement is suspended until
// finally block has completed
} finally {
return false; // overwrites the previous "throw"
}
// "return false" is executed now
}
try {
f();
} catch (e) {
// this is never reached because the throw inside
// the catch is overwritten
// by the return in finally
console.log('caught outer "bogus"');
}
// OUTPUT
// caught inner "bogus"
Error对象
DOMException、ECMAScript exceptions
function doSomethingErrorProne () {
if (ourCodeMakesAMistake()) {
throw (new Error('The message'));
} else {
doSomethingToGetAJavascriptError();
}
}
....
try {
doSomethingErrorProne();
}
catch (e) {
console.log(e.name); // logs 'Error'
console.log(e.message); // logs 'The message' or a JavaScript error message)
}