JavaScript学习笔记

前言

JavaScript Tutorial

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

e01cea6b05e732c947fb09571fa1a4ac.png

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)
  1. The addition with a string "" + 1 converts 1 to a string: "" + 1 = "1", and then we have "1" + 0, the same rule is applied.
  2. The subtraction - (like most math operations) only works with numbers, it converts an empty string "" to 0.
  3. null becomes 0 after the numeric conversion.
  4. 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 函数的声明

79abc9e015790dd326bb5345e4f4346a.png

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,结果是函数体。04444b325796d536b08da988daab4292.png
加上括号才是函数。

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
原文地址:https://www.cnblogs.com/hjs-junyu/p/9721043.html