JavaScript(缩写为JS)是一种高级的、解释型的编程语言。由ECMA(欧洲电脑制造商协会)通过ECMAScript实现语言的标准化,JavaScript是一门基于原型、函数先行的语言,是一门多范式的语言,它支持面向对象程序设计,命令式编程,以及函数式编程。
JavaScript语言的特点
Javascript一种基于对象(object-based)和事件驱动(EventDriven)的简单的并具有安全性能的脚本语言。
特点:
☆解释性:不用预编译,直接解析执行代码。
☆动态的,弱类型,基于原型的脚本语言。
动态的是指,在一个Javascript对象中,要为一个属性赋值,我们不必事先创建一个字段,只需要在使用的时候做赋值操作。
弱类型,在定义变量的时候,我们可以为变量赋值任何数据,变量的数据类型不是固定死的,这样的类型叫做弱类型,如:
var a = 10;
a = "abc";
a = [];
a = function(){};
JavaScript与Java,C/C++不同,JavaScript是弱类型的,它的数据类型无需在声明时指定,解释器会根据上下文对变量进行实例化。
JavaScript的变量更像是一个容器,类似与Java语言中的顶层对象Object,它可以是任何类型,解释器会根据上下文自动对其造型。
☆面向对象
JavaScript 语言标准已经明确说明,JavaScript 是一门面向对象的语言;
JavaScript是否属于“面向对象的语言”一直饱受争议,一些争论中,有人强调,JavaScript 并非“面向对象的语言”,而是“基于对象的语言”,这个说法也一度流传甚广。JavaScript 的对象设计跟目前主流基于类的面向对象差异非常大。而事实上,这样的对象系统设计虽然特别,但是 JavaScript 提供了完全运行时的对象系统,这使得它可以模仿多数面向对象编程范式,所以它也是正统的面向对象语言。而因为与基于类的面向对象的差异,我们也称JavaScript 为基于原型的面向对象。
☆事件驱动
JavaScript对用户的响应,是以事件驱动的方式进行的,所谓事件驱动,指的是在网页(Web Page)执行了某种操作所产生的动作(如按下鼠标、移动窗口、选择菜单等),此动作称为“事件”。当事件发生后,可能会引起相应的事件响应,执行某些对应的脚本,这种机制被称为“事件驱动”。
☆跨平台
JavaScript依赖于浏览器本身,与操作环境无关。只要能运行浏览器的计算机,并支持JavaScript的浏览器就可以正确执行。
☆其它
大小写敏感。
可以直接嵌入HTML页面,但写成单独的js文件有利于结构和行为的分离。
JavaScript脚本代码的执行顺序
JavaScript代码执行分为三个部分:
语法分析→预编译→解释执行
语法分析,在执行之前系统会先对JS进行全面扫描检查,查看是否存在语法错误。如果遇到错误,就会将该语法错误(syntaxError)抛出,并停止JS代码的执行。如果语法正确,则进入到预编译阶段。
预编译阶段,进行代码的检查装载,同样也是按从上到下按顺序进行的。此阶段只进行变量和函数的声明,会跳过执行语句,不对变量进行赋值,变量的默认值为undefined。即使声明是在调用的下方进行的,但浏览器仍然先声明再调用(执行),这个现象叫做“声明提升”。所以,即便一个函数的声明在函数调用的下方,前面仍然可以正常执行这个函数,需要注意的是,先进行变量声明再进行函数声明提升,如函数声明与变量声明的名称相同,函数声明会覆盖变量名声明。
执行阶段,此阶段对变量进行赋值和函数的声明。
JavaScript基本语法
JavaScript 语言是区分大小写的,不管是命名变量还是使用关键字的时候。在 JavaScript 中,关键字都是小写的。对于变量名,函数名、函数参数等,需要区分大小写,区分大小写,如A和a是两个不同的变量。
标识符(identifier)指的是用来识别各种值的合法名称。最常见的标识符有:变量名,函数名。在JavaScript中对象,变量、函数名都是区分大小写的。
标识符命名规则
第一个字符,可以是任意 Unicode 字母(运算符、数字除外),以及美元符号($)和下划线(_)。后面的字符可以用数字。
中文可以用作变量名。JavaScript有一些关键字(也叫保留字),不能用作标识符:arguments、break、case、catch、class、const、continue、debugger、default、delete、do、else、enum、eval、export、extends、false、finally、for、function、if、implements、import、in、instanceof、interface、let、new、null、package、private、protected、public、return、static、super、switch、this、throw、true、try、typeof、var、void、while、with、yield。
JavaScript 关键字要小写。
注释
注释用来对 JavaScript 进行解释,提高代码的可读性。JavaScript 不会执行注释。
Javascript 提供两种注释的写法:一种是单行注释,用//起头;另一种是多行注释,放在/*和*/之间。
// 这是单行注释
/* 这是多行 注释 */
表达式
表达式:由运算符和操作数组成的式子叫做表达式。如:1+2+3
每个表达式都有自己的值——表达式的值是表达式运算的结果。
运算符:能够完成数据计算的一组符号,比如:+、-、*、/ 。运算符无法单独构成表达式。关于运算符将在“JavaScript数据类型”一文中详细介绍。
操作数是一个表达式内的变量、常量、字面量。单独的操作数也是表达式——原子表达式,如10、“abc”。
语句(statement)是为了完成某种任务而进行的操作一般情况下,每一行就是一个语句。语句以分号结尾,但非必须。以分号结束语句不是必需的,但我们仍然强烈建议您这么做。
如果有分号分隔,允许在同一行写多条语句,如:
a = 5; b = 6; c = a + b;
可以将一行代码分成多行写,处字符串外,可以插入空格的地方就可以换行(折行)。
关键字、括号、二元运算符两侧必须有一个空格,一元运算符与操作对象之间不允许有空格;
如
if(2>1){console.log("这是真的")}else{console.log("这是假的")}
可以写为:
if ( 2 > 1) { console.log ( "这是真的" )} else { console.log ( "这是假的" )}
也可以写为:
if ( 2 > 1)
{ console.log ( "这是真的" )}
else { console.log ( "这是假的" )}
如果 JavaScript 语句太长,对其进行换行的最佳位置是某个运算符。
字符串的换行
Javascript中的字符串默认只能写在一行内,分成多行将会报错,如:
var str='long
long
string'
但改为下面两种方式,则可以:
方式一:
var str = 'Long \
long \
string'
方式二:
连接运算符(+)可以连接多个单行字符串,将长字符串拆成多行书写,输出的时候也是单行。这是推荐方式。
var str = 'Long '
+ 'long '
+ 'string';
变量
变量相当于容器,值相当于容器内装的东西,而变量名就是容器上贴着的标签,通过标签可以找到 变量,以便读、写它存储的值。
变量声明,可以在同一条var命令中声明多个变量。如:
var a, b;
您也可以在声明变量时对其赋值:
var carname="Volvo";
JavaScript 是一种动态类型语言,也就是说,变量的类型没有限制,变量可以随时更改类型。如:
var a = 1;
a = 'hello';
var语法
var varname1 [= value1] [, varname2 [= value2] ... [, varnameN [= valueN]]];
var可以重复声明变量
使用var声明变量时,在代码块内可以修改在代码块之外声明的变量。
使用var声明变量的变量在全局范围内都有效。
var 存在变量提升,在代码中的任意位置声明变量总是等于在代码开头声明。如:
a = 1
var a;
可以理解为:
var a;
a= 1;
【var声明语句,参见:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/var】
特别提示:与高级程序语言如C++、Java 等为强类型语言不同,JavaScript语言是弱类型语言,在变量声明时不需显式地指定其数据类型,变量的数据类型将根据变量的具体内容推导出来,且根据变量内容的改变而自动更改,而强类型语在变量声明时必须显式地指定其数据类型。变量声明时不需显式指定其数据类型既是 JavaScript 脚本语言的优点也是缺点,优点是编写脚本代码时不需要指明数据类型,使变量声明过程简单明了;缺点就是有可能造成因微妙的拼写不当而引起致命的错误。
由于JavaScript的动态性质,变量可以随时保存任何类型的值。
JavaScript并不强制类型,也就是说语言本身并不要求变量中值的类型必须一直和初始类型相同。变量中可以保存字符串,下一次赋值时可以保存数字,等等。
var a = 1;
typeof a; // "number"
a = false;
typeof a; // "boolean"
参见下图:
顺便说明:在控制台中使用关键字 var、let、const定义变量,将输出undefined,如:
var x; //输出undefined
var a=12; //输出undefined
将赋值后的变量作为单独的语句使用,将输出其值,如
console.log(a); // 12
x=5;
console.log(x); //5
参见下图:
关于数据类型,将在后续讲座中介绍。也可以像下面这样检查变量的类型:
var_str="abc123"; //字符串(String)
typeof var_str === "string"; //返回true
var_num=123; //数值(Number)
typeof var_num === "number";
var_boo=false; //布尔(Boolean)
typeof var_boo === "boolean"
参见下图:
let和const是JavaScript里相对较新的变量声明方式。
let语法
let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];
const语法
const name1 = value1 [, name2 = value2 [, ... [, nameN = valueN]]];
const定义的变量不可以修改,而且必须初始化。
let具有块级作用域,用let声明的变量,不存在变量提升。而且要求必须 等let声明语句执行完之后,变量才能使用。
let具有暂时性死区:
只要块级作用域内存在let命令,它所声明的变量就“绑定”这个区域,不再受外部的影响。
【let声明语句,参见:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let
const声明语句,参见:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/const
】
语句块
所谓语句块就是使用花括号{...}包含的多个语句,语句块是一个整体的执行体,类似于一个单独的语句。
【具体可参见
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/block
https://juejin.im/post/6844903951351939080
】
关于作用域(scope),将在“JavaScript函数”中继续介绍。
严格模式(Strict Mode)的使用
ECMAScript 5中的严格模式(strict mode)能够产生更清晰的代码,该模式减少了一些不安全的特性,增加了更多的警告信息,代码行为也更符合逻辑。普通(非严格)模式也叫作懒散模式(sloppy mode)。严格模式能够帮助你避免一些不够细致的编程实践。如果刚入手一个新的JavaScript项目,建议一开始就使用严格模式。
严格模式中的变量必须声明
在严格模式中,所有的变量必须明确声明,这有助于避免输入错误。在懒散模式中,对未声明的变量赋值会生成一个全局变量:
function sloppyFunc() {
sloppyVar = 123; // 创建全局变量sloppyVar
}
sloppyFunc();
console.log(sloppyVar); // 123
参加下图:
在严格模式中,对未声明的变量赋值会抛出异常:
function strictFunc() {
'use strict';
strictVar = 123;
}
strictFunc(); //报错
参见下图:
注意,不支持ECMAScript 5的JavaScript引擎会简单地忽略上面的语句,继续在非严格模式下运行。
在现代浏览器中开启严格模式非常容易,只需要在JavaScript代码中出现以下指令即可。严格模式可以在脚本或函数级别实现(即全局和局部模式)。
1.全局
在js文件的最前面添加 "use strict"
2.局部
在函数内部添加 "use strict",如下
function fn() {
"use strict";
//some code
}
不建议在全局环境下启用严格模式。