- 前言
- 1. JavaScript介绍
- 2. JavaScript基础知识
前言
1. JavaScript介绍
1.1 什么是JavaScript?
浏览器拥有嵌入式的引擎,被称为JavaScript 虚拟机。
chrome里面是v8引擎,火狐里面是SpiderMonkey引擎。
引擎如何工作:
- 引擎读取代码;
- 转换为及其语言;
- 运行代码,速度非常快;
1.2 JavaScript为什么特殊?
- 和html很好的交互;
2. JavaScript基础知识
2.1 Hello World
如果为sctipt
标签设置了src标签,那么content将会被忽视。
2.2 code strcture
语句是执行操作的语法结构和命令。
- Semicolons(分号)
大部分情况下会在行尾默认添加分号,但是有些情况下,不会添加。
还有一些情况,编辑器是很难确定的,会产生错误。
比如:
[1, 2].forEach(alert)
这样是没有任何问题的,但是如果我们这么写,将会出错:
alert("There will be an error")
[1, 2].forEach(alert)
Uncaught TypeError: Cannot read property '2' of undefined。
如果我们这样写,那么一切又是正常的了。
alert("All fine now");
[1, 2].forEach(alert)
不可以使用嵌套注释,因为这样将会报错。
/*
/* nested comment ?!? */
*/
2.3 "use strict"
自动2009年之后,ECMAScript 5(ES5)出现之后,添加了新的语言特性,同时修改了一些存在的代码,为了兼容性问题,必须使用"use strict"或者'use strict'在代码的最上面。
只有注释才可以出现在'use strict'上面。
2.4 变量Variables
var和let大部分情况下作用是相同的,但是有部分情况下,作用是不同的。
常量:使用const代替var或者let。
2.5 数据类型
动态类型,数据不会和数据类型进行绑定。
2.5.1 number
三个特殊值:
- Infinity:代表数学上的∞无穷大,可以这么来定义:
alert( 1 / 0 ); // Infinity
- NaN代表一个计算错误,代表数学上的不正确或者未定义的数学操作。另外如果其中一个数字是NaN,那么经过运算后,仍然是NaN,比如:
alert( "not a number" / 2 + 5 ); // NaN
我们可以在JavaScript做任何数学操作,都不会报错,而是会给一个NaN的结果。
2.5.2 string
双引号,单引号,和Backticks(反引号),前两者没有什么区别。
反引号可以用来嵌入(embed)一个变量和表达式在一个字符串中通过使用${…}
来包裹,例如:
let name = "John";
// embed a variable
alert( `Hello, ${name}!` ); // Hello, John!
// embed an expression
alert( `the result is ${1 + 2}` ); // the result is 3
2.5.3 boolean
2.5.4 null
不像其他语言的那样,指向一个不存在的对象或者空指针,代表的含义是nothing,empty或者value unknown。
2.5.5 undefined value
undefined的意思是值未分配。
undefined可以赋值给任何类型的变量。
但是一般情况下,用null来表示empty或者unknown,undefined用来检查变量是否被分配。
2.5.6 对象和符号Objects and Symbols
object类型是特殊的。
对象类型可以用来存储更加复杂的东西。
2.5.7 The typeof operator
快速判断给定值的类型,有两种语法:
- As an operator: typeof x.
- Function style: typeof(x).
typeof undefined // "undefined"
typeof 0 // "number"
typeof true // "boolean"
typeof "foo" // "string"
typeof Symbol("id") // "symbol"
typeof Math // "object" (1)
typeof null // "object" (2)
typeof alert // "function" (3)
值得注意的是:typeof null is "object"的判断是错误的,但是为了保持兼容性,事实上null is not an object。
另外,typeof alert is "function",事实上,函数类型属于对象类型,没有特殊的函数类型,这样表示只是为了方便。
2.5.8 总结
JavaScript中有7中基本类型:
- number的意思是interger或者浮点数;
- string:有一个或者多个字符,没有单个字符类型的;
- boolean:true或者false;
- null:unknown,具有单个值null的独立类型;
- undefined:unassigned值,只有一个undefined值的独立类型;
- object:用于复杂的数据结构;
- symbol:标识符;
2.6 类型转换
一般而言,operators and functions自动把值转换为正确的类型。比如,alert自动的把值转换为string去显示。
数学操作符自动的把值转换为numbers。
下面的情况下,我们需要明确的把值转换成正确的类型:
2.6.1 ToString
let value = true;
alert(typeof value); // boolean
value = String(value); // now value is a string "true"
alert(typeof value); // string
比如:false变为“false”,null变为“null”
2.6.2 ToNumber
这种情况自动发生在数学函数和表达式中。比如:
alert( "6" / "2" ); // 3, strings are converted to numbers
可以使用Number进行强制类型转换:
let str = "123";
alert(typeof str); // string
let num = Number(str); // becomes a number 123
alert(typeof num); // number
如果不是数字,将会返回一个NaN的错误。
let age = Number("an arbitrary string instead of a number");
alert(age); // NaN, conversion failed
alert( Number(" 123 ") ); // 123
alert( Number("123z") ); // NaN (error reading a number at "z")
alert( Number(true) ); // 1
alert( Number(false) ); // 0
null和undefined大部分情况相同,但是有些时候是不同的。
“+“连接的字符串:
几乎所有的算术操作符都可以把value转换为number,”+“不可以,如果一个是string,那么另外一个也将会被转换为string。
alert( 1 + '2' ); // '12' (string to the right)
alert( '1' + 2 ); // '12' (string to the left)
2.6.3 ToBoolean
false:0,empty string,null,undefined,NaN;
true:除了上面的值。
alert( Boolean(1) ); // true
alert( Boolean(0) ); // false
alert( Boolean("hello") ); // true
alert( Boolean("") ); // false
alert( Boolean(1) ); // true
alert( Boolean(0) ); // false
alert( Boolean("hello") ); // true
alert( Boolean("") ); // false
请注意:
JavaScript把非空字符串当做true。
alert( Boolean("0") ); // true
alert( Boolean(" ") ); // spaces, also true (any non-empty string is true)
2.6.4 总结
三个最常用的转换:
- ToString
- ToNumber
- ToBoolean
对象的转换不在这里进行叙述。
"" + 1 + 0 = "10" // (1)
"" - 1 + 0 = -1 // (2)
true + false = 1
6 / "3" = 2
"2" * "3" = 6
4 + 5 + "px" = "9px"
"$" + 4 + 5 = "$45"
"4" - 2 = 2
"4px" - 2 = NaN
7 / 0 = Infinity
" -9
" + 5 = " -9
5"
" -9
" - 5 = -14
null + 1 = 1 // (3)
undefined + 1 = NaN // (4)
- The addition with a string "" + 1 converts 1 to a string: "" + 1 = "1", and then we have "1" + 0, the same rule is applied.
- The subtraction - (like most math operations) only works with numbers, it converts an empty string "" to 0.
- null becomes 0 after the numeric conversion.
- undefined becomes NaN after the numeric conversion.
2.7 Operators
2.7.1 术语:“unary”, “binary”, “operand”
一元,二元,操作数
- 操作数:
- 一元运算符
- 二元运算符
2.7.2 字符串连接,二进制+
2.7.3 数字转换,一元运算符 +
用在number上,不会有任何影响,但是如果用在非数字上,可以进行转换。
// No effect on numbers
let x = 1;
alert( +x ); // 1
let y = -2;
alert( +y ); // -2
// Converts non-numbers
alert( +true ); // 1
alert( +"" ); // 0
起到的作用相当于Number(),但是写起来更短。
如果我们求和的结果呢?
let apples = "2";
let oranges = "3";
alert( apples + oranges ); // "23", the binary plus concatenates string
let apples = "2";
let oranges = "3";
// both values converted to numbers before the binary plus
alert( +apples + +oranges ); // 5
// the longer variant
// alert( Number(apples) + Number(oranges) ); // 5
虽然从数学的角度来看,十分的奇怪,但是从程序的角度来讲,+会被首先运算。
2.7.4 Operators precedence(运算符优先级)
2.7.5 Assignment
2.7.6 Remainder %
2.7.7 指数**
2.7.8 Increment/decrement(自增,自减)
2.7.9 Bitwise operators
2.7.10 Comma(逗号表达式)
2.8 Comparisons(比较运算符)
2.8.1 String comparison
按照字典序或者词典序进行排序。
比较的是unicode码。
2.8.2 不同类型的比较
当比较不同类型的时候,会被自动转换为numbers。
alert( '2' > 1 ); // true, string '2' becomes a number 2
alert( '01' == 1 ); // true, string '01' becomes a number 1
alert( true == 1 ); // true
alert( false == 0 ); // true
2.8.3 严格的相等
2.8.4 总结
- 比较运算符返回一个逻辑值。
- 字符串的比较是按照字典序进行排序的。
- 不同类型的值进行比较的时候,会转换为numbers
- null和undefined在不严格意义上是相等的,严格意义上是不相等的。
- 当使用>or <的时候,要注意null/undefined,在使用之前需要检查。
2.9 Interaction: alert, prompt, confirm
2.9.1 alert
2.9.2 prompt
该函数接受两个参数:
result = prompt(title[, default]);
包含一个用户输入框,一个按钮ok/cancel。
- title:显示给用户的文本;
- default:可选,默认的文本框的值。
2.9.3 confirm
result = confirm(question);
弹出一个询问框。
2.9.4 总结
- alert:显示一个信息;
- prompt:让用户输入信息,如果点解了cancel,将会返回null
- confirm:确认框,ok是true,cancel是false。
2.10 Conditional operators: if, '?'条件运算符
- Boolean转换:number 0,空字符串“”,null,undefined and NaN变成false。
- 其他值是true。
2.11 Logical operators,逻辑运算符
2.12 循环:while和for
2.13 switch
2.14 Functions
2.14.1 函数的声明
function showMessage() {
alert( 'Hello everyone!' );
}
showMessage();
showMessage();
2.14.2 局部变量
值得注意的是,JavaScript中,var无法声明块级作用域,let可以。
function showMessage() {
let message = "Hello, I'm JavaScript!"; // local variable
alert( message );
}
showMessage(); // Hello, I'm JavaScript!
alert( message ); // <-- Error! The variable is local to the function
2.14.3 Outer variables(外部变量)
2.14.4 参数
2.14.5 总结
函数的声明方式如下所示:
function name(parameters, delimited, by, comma) {
/* code */
}
- 值传递,参数,局部变量;
- 函数可以访问外部变量;
- 函数有返回值,如果没有返回,就是undefined;
为了函数更加的模块化,最好使用局部变量,少使用全局变量。
2.15 函数表达式和箭头
在JavaScript中,函数也是一种特殊的值,可以赋给一个变量。
let sayHi = function() {
alert( "Hello" );
};
此时sayHi保存的是函数体,如果调用sayHi,结果是函数体。
加上括号才是函数。
function sayHi() {
alert( "Hello" );
}
注意,sayHi不是一个函数,因为sayHi后面没有括号。
alert( sayHi ); //, shows the function code
一个函数可以copy给一个变量:
function sayHi() { // (1) create
alert( "Hello" );
}
let func = sayHi; // (2) copy,func保存的是函数体
//如果let func = sayHi();那么func保存的是函数的结果
func(); // Hello // (3) run the copy (it works)!
sayHi(); // Hello // this still works too (why wouldn't it)
2.15.1 回调函数
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
function showOk() {
alert( "You agreed." );
}
function showCancel() {
alert( "You canceled the execution." );
}
// usage: functions showOk, showCancel are passed as arguments to ask
ask("Do you agree?", showOk, showCancel);
ask(question, yes, no)有三个参数:
- question:问题;
- yes:如果answer是“Yes”的话,函数就会运行;
- no:如果answer是“no”的话,
2.15.2 Function Expression vs Function Declaration
函数声明中,调用可以在定义之前,比如:
sayHi("John"); // Hello, John
function sayHi(name) {
alert( `Hello, ${name}` );
}
但是,函数表达式,定义必须在调用之前,比如:
sayHi("John"); // error!
let sayHi = function(name) { // (*) no magic any more
alert( `Hello, ${name}` );
};
函数的声明仅在相应的块中有效,下面的代码中,welcome()函数仅在if的判断中是有用的。
let age = prompt("What is your age?", 18);
// conditionally declare a function
if (age < 18) {
function welcome() {
alert("Hello!");
}
} else {
function welcome() {
alert("Greetings!");
}
}
// ...use it later
welcome(); // Error: welcome is not defined
let age = 16; // take 16 as an example
if (age < 18) {
welcome(); // (runs)
// |
function welcome() { // |
alert("Hello!"); // | Function Declaration is available
} // | everywhere in the block where it's declared
// |
welcome(); // / (runs)
} else {
function welcome() { // for age = 16, this "welcome" is never created
alert("Greetings!");
}
}
// Here we're out of curly braces,
// so we can not see Function Declarations made inside of them.
welcome(); // Error: welcome is not defined
让welcome()函数在外面可用的方法是下面的,在外面声明welcome变量:
let age = prompt("What is your age?", 18);
let welcome;
if (age < 18) {
welcome = function() {
alert("Hello!");
};
} else {
welcome = function() {
alert("Greetings!");
};
}
welcome(); // ok now
2.15.3 Arrow functions
大概是这样:
let func = (arg1, arg2, ...argN) => expression