完整的JavaScript实现包含ECMAScript(核心)、DOM(文档对象模型)、BOM(浏览器对象模型)。
<script>元素
用于把JavaScript代码嵌入HTML页面中。也可用于引入保存在外部文件中的JavaScript。
属性:
- async:表示应该立即下载脚本,但不能阻止其他页面动作,即异步加载。只对外部脚本文件有效。
- defer:表示脚本可延迟到文档完全被解析和显示之后再执行,相当于告诉浏览器立即下载,但延迟执行。只对外部脚本文件有效。
- charset:使用src属性指定的代码字符集。少用。
- crossorigin:配置相关请求的CORS(跨源资源共享)。默认不适应CORS。
- integrity:允许比对接收到的资源和指定的加密前面以验证子资源完整性。用于确保内容分发网络不会提供恶意内容。
- src:表示包含要执行的代码的外部文件。
- type:表示代码块中脚本语言的内容类型。按照惯例,这个值始终都是“text/javascript”。
语法
标识符
即变量、函数、属性或函数参数的名称。
标识符的命名规则:【使用驼峰大小写形式】
- 第一个字符必须是一个字母,下划线(_)或美元符号($);
- 剩下的其它字符可以是字母、下划线、美元符号或数字。
eg firstSecond,myCar 关键字、保留字、true、false和null不能作为标识符。
变量
可以声明变量的三个关键字:var、const和let,var可在ECMAScript的所有版本中可以使用,而const和let只能在ECMAScript 6及更晚的版本中使用。
最佳实践:不使用var,const优先,let次之。
1.var关键字
可以保存任何类型的值,在不初始化的情况下,变量会保存一个特殊值undefined。
- var声明作用域 使用var定义的变量会成为包含它的函数的局部变量,比如,使用var在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁。
function test(){
var message = "hi";//局部变量
}
test();
console.log(message);// 出错!
- var声明提升 提升是指把所有变量声明都拉到函数作用域的顶部,即变量可以在声明之前使用,值为undefined。
function foo(){
console.log(age);
var age = 26;
}
foo(); //undefined
2.let声明[ ECMAScript6及以上版本 ]
所声明的变量,只在let命令所在的代码块内有效。 块级作用域有最近的一堆包含花括号{}界定。即if块、while块、function块以及单独的块都是let声明变量的作用域。
let与var的作用差不多,最明显的区别是,let声明的范围是块作用域,而var声明的范围是函数作用域。
if(true){
var name = ‘Matt’;
console.log(name);//Matt
}
console.log(name);//Matt
if(true){
let age = 26,
console.log(age);//26
}
console.log(age);//ReferenceError:age没有定义
- let在同一个块作用域中不能出现冗余声明。
重复的var声明会被忽略,而重复的let声明会抛出SyntaxError。
- let不存在变量提升 let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
在let声明之前的执行瞬间称为“暂时性死区”,在此阶段引用任何后面才声明的变量都会抛出ReferencenError。
- for循环中的let声明 在循环中声明迭代变量适合使用let声明。 迭代变量的作用域仅限于for循环块内部。
for(let i=0;i<5;++i){
setTimeout(() => console.log(i),0)
}//会输出0,1,2,3,4
console.log(i); //ReferencenError: i 没有定义
在使用let声明迭代变量时,JavaScript引擎在后台会为每个迭代循环声明一个新的迭代变量。每个setTimeout引用的都是不同的变量实例。
3.const声明[ ECMAScript6及以上版本 ]
const的行为与let基本相同,唯一一个重要的区别是用它声明变量是必须同时初始化变量,且尝试修改const声明的变量会导致运行时错误。
const声明的限制只适用于它指向的变量的引用。若const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制。
const person = {};
person.name = 'Matt'; //ok
数据类型
简单数据类型:Undefined、Null、Boolean、Number、String和Symbol(ES6新增)。
复杂数据类型:Object。是ES中所有对象的基类。
ES不区分整数和浮点值,只有Number一种数值数据类型。
- typeof操作符
let message = 'some string';
console.log(typeof message); //"string"
typeof null返回的是”Object“。因为特殊值null被认为是一个对空对象的引用。
- Undefined类型 默认情况下,任何未经初始化的变量都会取得undefined值。
语句
for-in语句
用于枚举对象中的非符号键属性。
所有可枚举的属性都会返回一次,但返回的顺序可能会因浏览器而异。
若for-in循环要迭代的变量是null或undefined,则不执行循环体。
for(const propName in Window)
{
document.write(propName);
}
for-of语句
用于遍历可迭代对象的元素。
for-of循环会按照可迭代对象的next()方法产生值的顺序迭代元素。
如果尝试迭代的遍历不支持迭代,则for-of语句会抛出错误。
for(const el of {2,4,6,8})
{
document.write(el);
}
标签语句
用于给语句加标签。典型的应用场景是嵌套循环。
start: for(let i=0; i < count; i++){
console.log(i);
}
start标签,可以在后面通过break或continue语句引用。
break和continue语句
break语句用于立即退出循环,强制执行循环后的下一条语句。
continue语句用于立即退出循环,但会再次从循环顶部开始执行。
with语句【不推荐使用】
用于将代码作用域设置为特定的对象。
使用的主要场景是针对一个对象反复操作,这时候将代码作用域设置为该对象,能提供便利。
let ga = location.search.substring(1);
let hostName = location.hostname;
let url = location.href;
//使用with语句后
with(location){
let gs = search.substring(1);
let hostName = hostname;
let url = href;
}
此处with语句用于连接location对象,意味这在这个语句内部,每个变量首先会被认为是一个局部变量。 如果没有找到该局部变量,则会搜索location对象,看它是否有一个同名的属性。 如果有,则该变量会被求值为location对象的属性。
函数
ECMAScript中的函数与其它语言中的函数不一样。
- 不需要指定函数的返回值,因为任何函数可以在任何时候返回任何值。
- 不指定返回值的函数,实际上会返回特殊值undefined。
- return语句 return语句也可以不带返回值。这时候,函数会立即停止执行并返回undefined。
常用于提前终止函数执行,并不是为了返回值。
- diff()函数用于计算两个数值的差。