简介
JavaScript 是一种轻量级的脚本语言,只合适嵌入更大型的应用程序环境,去调用宿主环境提供的底层 API(如浏览器和Node.js)。JS还可以操作PostgreSQL数据库。
历史
1995年12月4日,JavaScript语言被发布。ECMAScript是浏览器脚本语言的标准和规范,JavaScript是其中的一种实现。2009年ECMAScript 5.0发布。2015年,ECMAScript6 正式发布。
定义变量
不要使用var,因为会存在变量提升的情况。
console.log(a) // undefined
var a = 20
let定义变量,只在当前代码块内有效:
{
let a = 20
}
console.log(a) // ReferenceError: a is not defined.
```javascript
`const`如果定义常量,常量的值就不能改变:
const a = 1 a = 3 // TypeError: Assignment to constant variable.
`const`定义复杂类型的数据时,只能保证这个指针是固定的,并不能确保改变量的结构不变:
```javascript
const foo = {};
// 为 foo 添加一个属性,可以成功
foo.prop = 123;
foo.prop // 123
// 将 foo 指向另一个对象,就会报错
foo = {}; // TypeError: "foo" is read-only
区块
{
console.log('这是一个区块')
}
break可以跳出带有标签foo的代码块.
标签通常与break语句和continue语句配合使用,跳出特定的循环。
foo: {
console.log(1);
break foo;
console.log('本行不会输出');
}
console.log(2);
// 1
// 2
为了避免这种歧义,无法确定是对象还是代码块,一律解释为代码块。
{ foo: 123 }
条件语句
switch (fruit) {
case "banana":
// ...
break;
case "apple":
// ...
break;
default:
// ...
}
注意: break语句不能少,否则贯穿。
如果要使用范围变量 如case xx < 20:,则需要switch (true)。
数据类型
- 数值(number):整数和小数(比如
1和3.14)。 - 字符串(string):文本(比如
Hello World)。 - 布尔值(boolean):表示真伪的两个特殊值,即
true(真)和false(假)。 undefined:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值。null:表示空值,即此处的值为空。- 对象(object):各种值组成的集合。
对象是最复杂的数据类型,又可以分成三个子类型。
- 狭义的对象(object)
- 数组(array)
- 函数(function)
typeof运算符可以返回一个值的数据类型。
function f() {}
typeof f
// "function"
v
// ReferenceError: v is not defined
typeof v
// "undefined"
typeof window // "object"
typeof {} // "object"
typeof [] // "object"
typeof null // "object"
对象属性的操作
- 属性的RW
var foo = 'bar';
var obj = {
foo: 1,
bar: 2
};
//READ
obj.foo // 1
obj[foo] // 2
//WRITE
obj.foo = 'Hello';
obj['bar'] = 'World';
- 查看一个对象本身的所有属性,可以使用
Object.keys方法。也可以用for in比遍历
var obj = {a: 1, b: 2, c: 3};
for (var i in obj) {
console.log('键名:', i);
console.log('键值:', obj[i]);
}
delete命令用于删除对象的属性,删除成功后返回true。
var obj = { p: 1 };
Object.keys(obj) // ["p"]
delete obj.p // true
obj.p // undefined
Object.keys(obj) // []
in检查对象是否包含某个属性(键名)。同时使用hasOwnProperty方法判断是否为对象自身的非继承的属性。
var obj = {};
if ('toString' in obj) {
console.log(obj.hasOwnProperty('toString')) // false
}
with是操作同一个对象的多个属性时,方便。注意使用已经存在的属性。
var obj = {
p1: 1,
p2: 2,
p3: 3, //错误的访问
};
with (obj) {
p1 = 4;
p2 = 5;
}
// 等同于
obj.p1 = 4;
obj.p2 = 5;
theme: v-green highlight: an-old-hope
函数
声明
function命令声明的代码区块
function print(s) {
console.log(s);
}
变量赋值,将匿名函数(函数表达式)赋值给变量。
let print = function(s) {
console.log(s);
};
Function构造函数
var foo = new Function(
'return "hello world";'
);
函数的属性
函数的name属性返回函数的名字
let f2 = function () {};
f2.name // "f2"
函数的length属性返回函数预期传入的参数个数
function f(a, b) {}
f.length // 2
toString()方法返回一个字符串,内容是函数的源码。
arguments只在函数体内部使用,而且可以在运行时修改。arguments很像数组,但它是一个对象.
arguments对象带有一个callee属性,返回它所对应的原函数。
var f = function (one) {
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
//arguments[0] = 3;
//arguments[1] = 2;
Array.prototype.slice.call(arguments); //将类似数组的对象转为数组
}
f(1, 2, 3)
// 1
// 2
// 3
立即执行表达式
当作表达式时,函数可以定义后直接加圆括号调用。
var f = function f(){ return 1}();
(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();
eval命令
eval命令接受一个字符串作为参数,并将这个字符串当作语句执行。
eval('var a = 1;');
a // 1
数组
typeof [1, 2, 3] // "object"
var arr = ['a', 'b', 'c'];
Object.keys(arr)
// ["0", "1", "2"]
arr.length // 3
检查某个键名是否存在的运算符in,适用于对象,也适用于数组。
var arr = [ 'a', 'b', 'c' ];
2 in arr // true
'2' in arr // true
4 in arr // false
var arr = [1, , 1];
arr.length // 3
//如果数组的某个位置是空位,`in`运算符返回`false`。
1 in arr //index 1 返回false
arr[1] // 但是空位是可以读的 undefined
//使用`delete`命令删除一个数组成员,会形成空位,并且不会影响`length`属性。
delete arr[0] // [, , 1]
运算符
- 加法运算符:
x + y - 减法运算符:
x - y - 乘法运算符:
x * y - 除法运算符:
x / y - 指数运算符:
x ** y - 余数运算符:
x % y - 自增运算符:
++x或者x++ - 自减运算符:
--x或者x-- - 数值运算符:
+x - 负数值运算符:
-x
>大于运算符<小于运算符<=小于或等于运算符>=大于或等于运算符==相等运算符===严格相等运算符!=不相等运算符!==严格不相等运算符
- 取反运算符:
! - 且运算符:
&& - 或运算符:
|| - 三元运算符:
?:
- 二进制或运算符(or):
|,表示若两个二进制位都为0,则结果为0,否则为1。 - 二进制与运算符(and):
&,表示若两个二进制位都为1,则结果为1,否则为0。 - 二进制否运算符(not):
~,表示对一个二进制位取反。 - 异或运算符(xor):
^,表示若两个二进制位不相同,则结果为1,否则为0。 - 左移运算符(left shift):
<<,详见下文解释。 - 右移运算符(right shift):
>>,详见下文解释。 - 头部补零的右移运算符:
>>>。
数据类型转换
Number函数将字符串转为数值,要比parseInt函数严格很多
parseInt('42 cats') // 42
Number('42 cats') // NaN
`NaN` 属性代表一个“不是数字”的值, 但是它的类型,是 `Number`:
console.log(typeof NaN === "number"); // logs "true"
`NaN` 和任何东西比较——甚至是它自己本身!——结果是false
console.log(NaN === NaN); // logs "false"
String(123) // "123"
Boolean(true) // true
Boolean(false) // false
Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true 没错 就是true
错误处理
var err = new Error('出错了');
err.message // "出错了"
- message:错误提示信息
- name:错误名称(非标准属性)
- stack:错误的堆栈(非标准属性
使用
name和message这两个属性,可以对发生什么错误有一个大概的了解。
Error的6个派生对象。 SyntaxError对象是解析代码时发生的语法错误。ReferenceError对象是引用一个不存在的变量时发生的错误。RangeError对象是一个值超出有效范围时发生的错误TypeError对象是变量或参数不是预期类型时发生的错误。eval函数没有被正确执行时,会抛出EvalError错误。(不再使用)。- 支持自定义错误。
function UserError(message) {
this.message = message || '默认信息';
this.name = 'UserError';
}
UserError.prototype = new Error();
UserError.prototype.constructor = UserError;
new UserError('这是自定义的错误!');
throw
throw语句的作用是手动中断程序执行,抛出一个错误。程序就中止了。引擎会接收到throw抛出的信息
var x = -1;
if (x <= 0) {
throw new Error('x 必须为正数');
//throw new UserError('出错了!'); 也可以抛出自定义的错误
// 抛出一个数值
//throw 42;
}
// Uncaught Error: x 必须为正数
使用try catch对错误进行处理
finally代码块,不管是否出现错误,都会执行。但是如果有错误,finally执行了,后面的代码就不会执行了。
function f() {
try {
console.log(0);
throw 'bug';
} catch(e) {
console.log(1);
return true; // 这句原本会延迟到 finally 代码块结束再执行
console.log(2); // 不会运行
} finally {
console.log(3);
return false; // 这句会覆盖掉前面那句 return
console.log(4); // 不会运行
}
console.log(5); // 不会运行
}
var result = f();
// 0
// 1
// 3
result
// false
控制台相关
console.logconsole.warn黄色三角console.error红色的叉console.table将复合类型的数据,转为表格显示。console.count方法用于计数,输出它被调用了多少次。console.dir以易于阅读和打印的格式显示。console.dirxml以目录树的形式,显示 DOM 节点。console.assert断言console.time方法表示计时开始,console.timeEnd方法表示计时结束。console.group(console.groupCollapsed)和console.groupEnd将信息分组显示。console.trace显示当前执行的代码在堆栈中的调用路径。console.clear用于清除所有输出。$_属性返回上一个表达式的值。getEventListeners(object)方法返回一个对象。monitorEvents允许监听同一大类的事件。debugger作用是设置断点。