贡献者: addis
JavaScript 常见于网页中,一般浏览器都可以运行。我们以 Chrome 浏览器为例演示 Hello World
程序。
<!DOCTYPE html>
<html>
<body>
<div id = a></div>
<script>
console.log("hello world 1");
window.alert("hello world 2");
document.getElementById("a").innerHTML = "hello world 3";
document.write("hello world 4");
</script>
<script src="mycode.js"></script>
</body>
</html>
把这段程序复制到一个文本文件,并命名为 test.html
,用 Chrome 打开即可自动运行。按 F12 可打开调试窗口和命令行。
<script>...</script>
中的 4 行程序就是 JavaScript,它们这里分别演示了用 4 种不同的方法显示 “hello world”:
<div>...</div>
元素中
<script>
之前
在用 Chrome 调试时,可以用 F12 打开调试窗口,可以实现逐行调试,查看错误和警告信息和命令行输出等。
.vscode/launch.json
设置文件,不用做任何改动,现在就可以 debug 了。
F5,F10,F11
是连续执行,下一行,步入(step in)。
node
进入 REPL。
node
中的 JS 是有许多不一样的(例如 window
对象只有浏览器才有)。
Babel
可以把较新的 JS 版本转译(transpile)成较老的版本
<head>
和 <body>
中任意位置可以包含任意多个 <script>
<script src="路径/文件名.js 或者 url.js"></script>
插入代码文件
'use strict'
后使用严格语法。例如不声明的变量会出错,又例如不能使用 with
。
// 注释
或 /*注释*/
;
可以省略(取决于代码风格)
$
在变量/函数名中相当于一个字母,单独一个或几个 $
可以作为变量/函数名
;
不是必须的,可用于在同一行中分隔两个命令。
person = prompt("提示", "默认");
<button onclick="函数名()">按钮文字</button>
<input id="b"><br>
document.getElementById('b').value
file:///
。严重不推荐通过降低浏览器安全选项来解决。
%
,++
,--
,+=
,-=
&&
,||
, &
,|
,条件?语句1:语句2
**
,另有 **=
==
判断值,===
判断值和类型。同理 !=
和 !==
let a = 1, b = 2
或者用 const
和 var
var
是全局变量,且可以重新声明,let
和 const
是局部的
typeof()
获取变量类型
number
(不区分整数和浮点数,浮点是双精度),string
(单引号双引号通用,没有 char
类型)
object
'...'
和 "..."
是完全等效的字符串。唯一的区别是 '...'
中允许直接使用双引号,"..."
中允许直接使用单引号。如果你在里面的引号前面加上反斜杠则无论外面是什么都可以,如 "ab'cde\'fg\"hi"
表示 ab'cde'fg"hi
。
str[ind]
或 .charAt(ind)
可以获取字符串的某个字符
slice(startIndex, endIndex)
可以或取子串(不包括 endIndex
)
str.slice(-N);
可以获取最后 N
个字符。
字符串 + 字符串
,也可以 字符串 + 数字
num.toString()
可以数字变字符串,num.toPrecision(有效数字)
可以四舍五入到有效数字
parseInt("123")
,parseFloat("12.3e2")
Number(str)
既可以转换整数也可以转换小数
.toUpperCase()
和 .toLowerCase()
将所有字母变为大小写
v = [1, 'a', [2, 'b']]
,typeof
返回 object
,可以嵌套
v[0]
,v[2][1]
v.length
console.table()
可以显示二维数组
a.push(元素)
在最后新增元素,a.pop()
删除最后一个元素
a.shift()
删除第一个元素,a.unshift(元素)
新增元素到第一个
v.slice(i, j)
,复制从 i
到 j-1
个元素,注意没有 view
a = [1,2,3]; b = a; c = [1,2,3]
会有 a == b
,a === b
,c
永远不等于 a
和 b
。改变 a
的一个元素 b
也会变,
[a,b] = [1.1, 'hi']
可以分别对逐个元素赋值。如果左边要忽略哪个元素,直接不写即可,如 [, b]
或 [a, ]
。
if (条件) {...}
for (var i = 0; i < N; i++) {...}
const array = [10, 20, 30, 40, 50];
for (const item of array)
console.log(item);
function myFunction(p1, p2) {return p1 * p2;}
,return
可选
funA
调用 funB
,那么 funA
仍然可以在 funB
前面定义。可以理解为解释器从上到下一边读代码一边执行,读函数定义的以后并不会执行,一个函数真正被执行的时候需要保证解释器已经读过它的定义。
let myfun = function(){...}
是一个(匿名)函数的定义,可以作为另一个函数的变量,相当于把某个函数名作为变量。myfun
的类型为 function
。
(function(){...})()
叫做 Immediately-Invoked Function Expression (IIFE),可以立即执行 ...
中的代码而避免污染当前范围的变量名。
let myvar = (function(){...})()
。注意 myvar
是返回值不是函数句柄!
arguments
是一个类似于数组的对象,arguments[i]
是每个函数参数,arguments.length
是实际输入参数的个数。
(arg1, arg2) => { ... }
或者 arg1 => {...}
也可以定义匿名函数,或者叫箭头函数。比起普通函数,只有 ...
中的 this
会有区别。
[var1,var2,...]
即可。调用函数时可以用 [a,b] = myfun()
。
var d = new Date()
用于获取当前日期和时间 object,成员函数有 .getDay()
(获取星期几),.getMonth()
,.getFullYear()
,.getHours()
,.getMinutes
,
.getSeconds()
,.getMilliseconds
,.getTime()
(返回从 1970/01/01/0:00 到当前的时长)
const { exec } = require('child_process');
# 第二个参数是可选的,连逗号一起删掉即可
exec('命令 参数1 参数2', { shell: '/bin/bash' }, (error, stdout, stderr) => {
if (error) {
console.error(`Error executing command: ${error}`);
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
car = {name:"a", model:"500", color:"white"};
car.name
console.table()
可以列表显示属性
定义成员函数,可以使用关键词 this
const person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function() {
// this 不可省略
return this.firstName + " " + this.lastName;
}
};
Constructor 的例子(参考)
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
this.name = function() {
return this.firstName + " " + this.lastName;
};
}
要用该 constructor 创建对象,调用时必须用 new
,如 let person1 = new Person('1','2',3,'4')
。
this
最好理解,就是指当前对象。
this
在 'use strict'
时是 undefined
。否则在浏览器中是 windows
,而在 node 中是 global
this
。
button.addEventListener('click', function() {...})
,函数中的 this
指的是 DOM 中的对象(即 button
)。
http://
和 https://
协议,不能用 file://
协议。
file:///C:/路径/diffus.html
但浏览器上可能不会显示 file://
。注意第三个 /
表示电脑的根目录。
<script type="module"> import message from "./message.js"; </script>
const name = "Jesse"; const age = 40; export {name, age};
export const age = 40;
export function myfun() {...};
import { name, age } from "路径/文件.js";
,其中 .js
拓展名可以省略
export default age;
也可以在定义前面直接用 export default const age = 40;
。
import 重命名 from './myModule.js';
import { greet as sayHello, age as hisAge } from './myModule.js';
import * as MyModule from './myModule.js';
,所有的名字前面需要加 MyMOdule.
。
import * from ...
,必须要有 namespace
new Set();
,new Set([1, 2, 3, 4]);
mySet.clear();
mySet.add(3);
mySet.has(3);
math.js
和内建的 Math 库兼容(可以一起用)。注意这不是一个模块,不需要 import,可以用 file://
协议。
在代码前面插入 <script src="math.js"></script>
,也可以是 url 如 https://cdnjs.cloudflare.com/ajax/libs/mathjs/10.0.2/math.js
math.
,也可以在非 strict mode
下把代码放到 with (math) {...}
中
pi
,e
,
round
,ceil
, floor
,exp
,sin
,cos
,sqrt
,log
,atan2
,pow
random()
生成 0 到 1 的随机数,或者 random(min, max)
,random([Nr,Nc])
生成 0 到 1 的随机矩阵,random([Nr, Nc], min, max)
等。
let c = math.complex(2, 3)
生成复数
c.re
和 c.im
获取实部和虚部,可以赋值 c.re = 5
。也可以用 math.re(c)
和 math.im(c)
,不能赋值。
c.conjugate()
或者 math.conj(c)
,绝对值 math.abs(c)
或 c.abs()
,辐角 math.arg(c)
或者 c.arg()
,加法 math.add(a, b)
,乘法 math.multiply(a, b)
,除法 math.divide(a, b)
,根号 math.sqrt(-4)
,倒数 a.inverse()
。
zeros([Nc, Nr])
,ones([Nc, Nr])
range(2, 5)
size(矩阵)
获取矩阵尺寸,又如 size(矩阵)[1]
获取列数
a.resize([2, 3])
变形为零矩阵
det(矩阵)
multiply(矩阵1, 矩阵2)
lusolve(A, b)
解线性方程组
xxx.js.map
。浏览器的开发者工具可以根据该文件自动把 minify 的 js 显示为原来的源码。要使用 source map,一般 js 文件的最后会有一行类似于 //# sourceMappingURL=app.min.js.map
的注释,指定 source map 的位置,浏览器会根据这个读取 map 文件。该文件把 minified 代码 map 到源码文件的位置,所以也要保证源码文件存在才行。
src/
文件夹一般是源代码,dist/
(distribution)文件夹一般是 minify 的生产环境代码。