JavaScript基础精简版1(语言基础)

121 阅读5分钟

简介

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):整数和小数(比如13.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:错误的堆栈(非标准属性 使用namemessage这两个属性,可以对发生什么错误有一个大概的了解。
    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.log
  • console.warn 黄色三角
  • console.error 红色的叉
  • console.table 将复合类型的数据,转为表格显示。
  • console.count方法用于计数,输出它被调用了多少次。
  • console.dir以易于阅读和打印的格式显示。
  • console.dirxml以目录树的形式,显示 DOM 节点。
  • console.assert 断言
  • console.time方法表示计时开始,console.timeEnd方法表示计时结束。
  • console.groupconsole.groupCollapsed)和console.groupEnd将信息分组显示。
  • console.trace显示当前执行的代码在堆栈中的调用路径。
  • console.clear用于清除所有输出。
  • $_属性返回上一个表达式的值。
  • getEventListeners(object)方法返回一个对象。
  • monitorEvents允许监听同一大类的事件。
  • debugger作用是设置断点。