文章目录
1 什么是JavaScript
JavaScript 是一种脚本,一门编程语言,它可以在网页上实现复杂的功能,网页展现给你的不再是简单的静态信息,而是实时的内容更新,交互式的地图,2D/3D 动画,滚动播放的视频等等。
1.1 浏览器 API
内建于 web 浏览器中,它们可以使周边计算环境的数据暴露出来,还可以做实用的复杂工作。例如:
- 文档对象模型 API(DOM(Document Object Model)API) 能通过创建、移除和修改 HTML,为页面动态应用新样式等手段来操作 HTML 和 CSS。比如当某个页面出现了一个弹窗,或者显示了一些新内容(像上文小 demo 中看到那样),这就是 DOM 在运行。
- 地理位置 API(Geolocation API) 获取地理信息。这就是为什么 谷歌地图 可以找到你的位置,而且标示在地图上。
- 画布(Canvas) 和 WebGL API 可以创建生动的 2D 和 3D 图像。人们正运用这些 web 技术制作令人惊叹的作品。参见 Chrome Experiments 以及 webglsamples。
- 诸如 HTMLMediaElement 和 WebRTC 等 影音类 API 让你可以利用多媒体做一些非常有趣的事,比如在网页中直接播放音乐和影片,或用自己的网络摄像头获取录像,然后在其他人的电脑上展示(试用简易版 截图 demo 以理解这个概念)。
1.2 第三方 API
并没有默认嵌入浏览器中,一般要从网上取得它们的代码和信息。比如:
- Twitter API 和 新浪微博 API 可以在网站上展示最新推文之类。
- 谷歌地图 API 和 高德地图 API 可以在网站嵌入定制的地图等等。
1.3 注释
JavaScript 的注释和C++ 一样: //单行注释
和 /*多行注释 */
1.4 解释代码 vs 编译代码
解释(interpret)和 编译(compile)。在解释型语言中,代码自上而下运行,且实时返回运行结果。代码在执行前,无需由浏览器将其转化为其他形式。
与此同时,编译型语言代码能够运行之前需要先转化(编译)成另一种形式。比如 C/C++ 先被编译成汇编语言,然后才能由计算机运行。JavaScript 是轻量级解释型语言。两种方式各有优势。
1.5 服务器端代码 vs 客户端代码
客户端(client-side)代码是在用户的电脑上运行的代码,在浏览一个网页时,它的客户端代码就会被下载,然后由浏览器来运行并展示。这就是客户端 JavaScript。
而服务器端(server-side)代码在服务器上运行,浏览器将结果下载并展示出来。流行的服务器端 web 语言包括:PHP、Python、Ruby、ASP.NET 以及 JavaScript。JavaScript 也可用作服务器端语言,比如现在流行的 Node.js 环境。
1.6 动态代码 vs 静态代码
“动态”一词既能描述客户端 JavaScript,又能描述服务器端语言。是指通过按需生成新内容来更新 web 页面 / 应用,使得不同环境下显示不同内容。服务器端代码会在服务器上动态生成新内容,例如从数据库中提取信息。而客户端 JavaScript 则在用户端浏览器中动态生成新内容,比如说创建一个新的 HTML 表格,用从服务器请求到的数据填充,然后在网页中向用户展示这个表格。两种情况的意义略有不同,但又有所关联。
没有动态更新内容的网页叫做“静态”页面,所显示的内容不会改变。
1.7 怎样向页面添加 JavaScript
使用<script>
元素添加各种JavaScript:无论内部还是外部。
1.7.1 内部 JavaScript
code 直接加到html中,放在</head>
标签之前。
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>Apply JavaScript example</title>
<script>
// JavaScript goes here
document.addEventListener("DOMContentLoaded", function() {
function createParagraph() {
let para = document.createElement('p');
para.textContent = 'You clicked the button!';
document.body.appendChild(para);
}
const buttons = document.querySelectorAll('button');
for(let i = 0; i < buttons.length ; i++) {
buttons[i].addEventListener('click', createParagraph);
}
});
</script>
</head>
<body>
<button>Click me</button>
</body>
</html>
1.7.2 外部 JavaScript
外部JavaScript是指,将JavaScript脚本放到.js
文件中,这是最佳的写法,HTML和JS分开,易于维护,可重用。
function createParagraph() {
let para = document.createElement('p');
para.textContent = 'You clicked the button!';
document.body.appendChild(para);
}
const buttons = document.querySelectorAll('button');
for(let i = 0; i < buttons.length ; i++) {
buttons[i].addEventListener('click', createParagraph);
}
然后将<script> ...</script>
替换成:<script src="script.js" defer></script>
1.7.3 内联 JavaScript 处理器
有时候会看到下面这样的代码,即在button元素里加一个onclick
处理器,但是这是不好的写法,且每加一个button都要这样写,不好维护。
// !!!!!!!!!!!! bad practice! 不好的写法,HTML和JS混合在一起
function createParagraph() {
let para = document.createElement('p');
para.textContent = 'You clicked the button!';
document.body.appendChild(para);
}
<button onclick="createParagraph()">Click me!</button>
1.8 脚本加载策略
如果要用JS操作DOM,那么DOM一定要先于javascript被加载。
老的解决方法是将JS脚本放在</body>
标签之前,这种方法使HTML DOM在加载之前,javascript的加载/解析完全被阻止,效率低。
1.8.1 async
和 defer
1.7.1 内部 javascript 的例子:
document.addEventListener("DOMContentLoaded", function() {
...
});
事件监听器监听 DOMContentLoaded
事件,代表HTML body已经完全加载并解析。此事件被触发之后,javascript 才会运行。
async
和 defer
仅对外部 javascript 起作用,它们之间的区别示意图:
<script src="myscript.js"></script>
<script async src="myscript.js"></script>
<script defer src="myscript.js"></script>
- Without async or defer, browser will run your script immediately, before rendering the elements that’s below your script tag.
- With async (asynchronous), browser will continue to load the HTML page and render it while the browser load and execute the script at the same time.
- With defer, browser will run your script when the page finished parsing. (not necessary finishing downloading all image files. This is good.)
<script defer src="js/vendor/jquery.js"></script>
<script defer src="js/script2.js"></script>
<script defer src="js/script3.js"></script>
使用defer能保证脚本按顺序加载,jquery.js, script2.js, script3.js ,使用 async 则不然。
如果多个脚本不需要等待解析(???),能独立执行,用async
, 反之用defer
。
2 初次接触 JavaScript
JavaScript 的很多代码特性和其他编程语言是一样的,比如函数啊,循环之类的,代码语法看起来不同,但概念基本是一样的。
用关键字let
(或 var
创建变量),用 const
创建常量(这点和C++一样)。
定义函数有很多方式,其中一种是用关键字function
定义,举例如下:
function checkGuess() {
alert('I am a placeholder');
}
如果在浏览器的JavaScript Console调用这个函数,会弹出对话框。
操作符 +
-
*
/
可以进行算术运算,还可以进行字符串连接。
还允许快捷操作符:
name += ' says hello!';
++
操作符也可以用: guessCount++;
比较操作符,这里比较相等和不等与其他语言不同,多一个等号。
但是 ==
和!=
在JavaScript里也是合法的操作符,但和严格相等符号===
相比,==
只看值是否相等,不管数据类型是否相同,因此应该使用===
符号,可以减少错误发生的可能性。
条件,if
, else if
, else
和C++ 语法是一样的。
对于JavaScript语言,一切都是对象,用户可以自己创建对象。
3 出现了什么问题?JavaScript 疑难解答
JavaScript 大小写敏感。
console.log()
是非常有用的调试函数,可以将值输出到控制台。
类选择器以点号 .
开始。
如果是Firefox, 用 Ctrl + Shift + K, 打开console,可以看到可能的错误提示。
4 储存你所需的信息 — 变量
4.1 用let
或var
声明变量
声明变量时不需要指定类型:
let myName;
let myAge;
在JavaScript中,所有代码指令以分号结束。
同时声明并初始化变量:
let myDog = 'Rover';
var
和let
的区别:
var
是老的,let
是新的,可以在变量初始化之后,再次用var
关键字声明。例如:
myName = 'Chris';
function logName() {
console.log(myName);
}
logName();
var myName;
此外,下面的代码是合法的,如果var
改成let
就不合法:
var myName = 'Chris';
var myName = 'Bob';
要尽量使用let
而非 var
,除非是要支持旧版的IE,一些旧版的IE只支持var
,不支持let
。
4.2 变量命名规则:
- 1 变量名由(0-9, a-z, A-Z) 以及下划线组成
- 2 不要以下划线开头
- 3 不要以数字开头
- 4 不能用保留字当变量名
4.3 变量类型:
- 数字:有整型,也有浮点型,
let myAge = 17;
- 字符串 :可用单引号或双引号,
let dolphinGoodbye = 'So long and thanks for all the fish';
- 布尔:值为
true
或false
,let iAmAlive = true;
- 数组:
let myNameArray = ['Chris', 'Bob', 'Jim'];
第一个元素的index是0 - 对象:
let dog = { name : 'Spot', breed : 'Dalmatian' };
然后dog.name
为Spot
动态类型:不需要指定变量的数据类型
let myNumber = '500'; // oops, this is still a string
typeof myNumber; // return "string"
myNumber = 500; // much better — now this is a number
typeof myNumber; // return "number"
4.4 常量
常量声明之后,值不可再次改变,和其他语言一样。
使用const
关键字:
const daysInWeek = 7;
const hoursInDay = 24;
daysInWeek = 8; // 抛出错误:TypeError: invalid assignment to const `daysInWeek'
5 JavaScript 基础概念 — 数字与运算符
5.1 JavaScript 只有一种数字的数据类型: Number
.
let myInt = 5;
let myFloat = 6.667;
myInt; // 5
myFloat; // 6.667
typedef myInt; // “number”
typedef myFloat; // "number"
5.2 操作符
操作符和其他语言类似, 有 +
-
*
/
%
**
, 最后一个是指数运算符:
10 ** 3
= Math.pow(10, 3)
= 10 * 10 * 10
= 1000
除法运算和python类似,会给出浮点值:
10 / 9;
1.1111111111111112
表达式求和的顺序总是从左到右。
++
和 --
操作符和C++的一样。
let num1 = 4;
num1++; //4
num1; //5
let num2 = 6;
num2--; //6
num2; //5
let num3 = 6;
++num3; //7
num3; //7
6 处理文字 — JavaScript 中的字符串
6.1 字符串
字符串可用单引号或双引号,但是不能混用:
let badQuotes = 'What on earth?"; // ERROR!!!!!
6.2 转义
转义字符串中的字符,在字符前加反斜杠转义字符:
let bigmouth = 'I\'ve got no right to take my place...';
bigmouth; // "I've got no right to take my place..."
6.3 连接字符串:
用+
号,字符串字面值还可以和变量相加:
let name = prompt('What is your name?');
alert('Hello ' + name + ', nice to see you!');
数字可与字符串相加:
'Front ' + 242; // OK, "Front 242"
6.4 数字与字符串相互转换
使用Number函数与toString() 方法:
let myString = '123';
let myNum = Number(myString);
typeof myNum; // "number"
let myNum = 123;
let myString = myNum.toString();
typeof myString; // "string"
7 字符串常用操作
字符串是对象。
7.1 字符串长度
使用 length
属性
let browserType = 'mozilla';
browserType.length; // 7
7.2 检索
同数组:
browserType[0]; // 使用索引,从0开始
browserType.indexOf('zilla'); // 如果未查找到,返回 -1, 判断时,可使用 !== -1
indexOf()
方法仅返回首次出现时的索引:The index of the first occurrence of searchValue, or -1 if not found.
7.3 字串
用 slice(a, b)
方法,a
为起始位置,b
为结束位置,实际取a ~ b-1
。 如果 b
省略,取a
起始的全部字符,直到结束。
let browserType = "Mozilla";
browserType.slice(2); // 'zilla';
7.4 大小写转换
分别使用 toLowerCase()
和 toUpperCase()
两个方法。
7.4 字符串替换
let browserType = "Mozilla";
browserType.replace('moz','van'); // 仅对第一个匹配项进行替换
8 数组
8.1 创建数组
数组元素的数据类型可以不统一:
let random = ['tree', 795, [0, 1, 2]];
8.2 访问和修改数组元素
同C++数组,没有特别之处。
8.3 数组长度
使用 .length
属性。
8.4 数组和字符串相互转换
8.4.1 字符串转换为数组
let myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle';
let myArray = myData.split(',');
myArray; //
8.4.2 数组转换为字符串
使用 join()
或 toString()
方法, toString()
更简单,但不能带参数。
let dogNames = ['Rocket','Flash','Bella','Slugger'];
let myNewString = dogNames.join(';;');
myNewString; //"Rocket;;Flash;;Bella;;Slugger"
let myNewString2 = dogNames.toString();
myNewString2; // "Rocket,Flash,Bella,Slugger"
8.5 添加和删除数组元素
从数组末尾添加删除元素: push()
, pop()
push()
可以带多个参数,如果成功,返回新数组长度,pop()
不带参数,如果成功,返回被删除的元素。
从数组开头添加删除元素:unshift()
, shift()
两组方法没有差别,只不过是一个对数组末尾的元素操作,一个对数组开头的元素操作。
let myArray = ['Manchester', 'London', 'Birmingham', 'Leeds', 'Carlisle'];
let newLength = myArray.push('Bradford', 'Brighton');
myArray; // Array(7) [ "Manchester", "London", "Birmingham", "Leeds", "Carlisle", "Bradford", "Brighton" ]
newLength; // 7
let removedItem = myArray.pop();
myArray; // Array(6) [ "Manchester", "London", "Birmingham", "Leeds", "Carlisle", "Bradford" ]
removedItem; // "Brighton"
https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/First_steps/What_is_JavaScript
https://stackoverflow.com/questions/10808109/script-tag-async-defer/24183280#24183280