JavaScript 的一些基础知识
JavaScript基本语法
调试
打开 Chrome 开发工具
Win
F12Mac
Command + Option + I
输入代码、测试执行
var str = 'evenyao'
console.log(str)
语句
JavaScript程序的执行单位为行(line),也就是一行一行地执行。一般情况下,每一行就是一个语句。
语句(statement)是为了完成某种任务而进行的操作,比如下面就是一行赋值语句:
var a = 1 + 3;
这条语句先用var
命令,声明了变量a
,然后将1 + 3
的运算结果赋值给变量a
。
1 + 3
叫做表达式(expression),指一个为了得到返回值的计算式。语句和表达式的区别在于,前者主要为了进行某种操作,一般情况下不需要返回值;后者则是为了得到返回值,一定会返回一个值。
凡是JavaScript语言中预期为值的地方,都可以使用表达式。比如,赋值语句的等号右边,预期是一个值,因此可以放置各种表达式。一条语句可以包含多个表达式。
语句以分号结尾,一个分号就表示一个语句结束。多个语句可以写在一行内。
var a = 1 + 3 ; var b = 'abc';
分号前面可以没有任何内容,JavaScript引擎将其视为空语句。
;;;
上面的代码就表示3个空语句。(关于分号的更多介绍,请看后文《代码风格》一节。)
表达式不需要分号结尾。一旦在表达式后面添加分号,则JavaScript引擎就将表达式视为语句,这样会产生一些没有任何意义的语句。
1 + 3;
'abc';
上面两行语句有返回值,但是没有任何意义,因为只是返回一个单纯的值,没有任何其他操作。
变量
概念
变量是对“值”的引用,使用变量等同于引用一个值。每一个变量都有一个变量名。
var a = 1;
上面的代码先声明变量a
,然后在变量a
与数值1之间建立引用关系,也称为将数值1“赋值”给变量a
。以后,引用变量a
就会得到数值1。最前面的var
,是变量声明命令。它表示通知解释引擎,要创建一个变量a
。
变量的声明和赋值,是分开的两个步骤,上面的代码将它们合在了一起,实际的步骤是下面这样。
var a;
a = 1;
如果只是声明变量而没有赋值,则该变量的值是undefined
。undefined
是一个JavaScript关键字,表示“无定义”。
var a;
a // undefined
如果变量赋值的时候,忘了写var
命令,这条语句也是有效的。
var a = 1;
// 基本等同
a = 1;
但是,不写var
的做法,不利于表达意图,而且容易不知不觉地创建全局变量,所以建议总是使用var
命令声明变量。
严格地说,
var a = 1
与a = 1
,这两条语句的效果不完全一样,主要体现在delete
命令无法删除前者。不过,绝大多数情况下,这种差异是可以忽略的。
如果一个变量没有声明就直接使用,JavaScript会报错,告诉你变量未定义。
x
// ReferenceError: x is not defined
上面代码直接使用变量x
,系统就报错,告诉你变量x
没有声明。
可以在同一条var
命令中声明多个变量。
var a, b;
JavaScript 是一种动态类型语言,也就是说,变量的类型没有限制,可以赋予各种类型的值。
var a = 1;
a = 'hello';
上面代码中,变量a
起先被赋值为一个数值,后来又被重新赋值为一个字符串。第二次赋值的时候,因为变量a
已经存在,所以不需要使用var
命令。
如果使用var
重新声明一个已经存在的变量,是无效的。
var x = 1;
var x;
x // 1
上面代码中,变量x
声明了两次,第二次声明是无效的。
但是,如果第二次声明的同时还赋值了,则会覆盖掉前面的值。
var x = 1;
var x = 2;
// 等同于
var x = 1;
var x;
x = 2;
变量提升
JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。
console.log(a);
var a = 1;
上面代码首先使用console.log
方法,在控制台(console)显示变量a的值。这时变量a
还没有声明和赋值,所以这是一种错误的做法,但是实际上不会报错。因为存在变量提升,真正运行的是下面的代码。
var a;
console.log(a);
a = 1;
最后的结果是显示undefined
,表示变量a
已声明,但还未赋值。
请注意,变量提升只对var
命令声明的变量有效,如果一个变量不是用var
命令声明的,就不会发生变量提升。
console.log(b);
b = 1;
上面的语句将会报错,提示“ReferenceError: b is not defined”,即变量b
未声明,这是因为b
不是用var
命令声明的,JavaScript引擎不会将其提升,而只是视为对顶层对象的b
属性的赋值。
标识符
标识符(identifier)是用来识别具体对象的一个名称。最常见的标识符就是变量名,以及后面要提到的函数名。JavaScript语言的标识符对大小写敏感,所以a
和A
是两个不同的标识符。
标识符有一套命名规则,不符合规则的就是非法标识符。JavaScript引擎遇到非法标识符,就会报错。
简单说,标识符命名规则如下:
- 第一个字符,可以是任意Unicode字母(包括英文字母和其他语言的字母),以及美元符号(
$
)和下划线(_
)。 - 第二个字符及后面的字符,除了Unicode字母、美元符号和下划线,还可以用数字
0-9
。
下面这些都是合法的标识符。
arg0
_tmp
$elem
π
下面这些则是不合法的标识符。
1a // 第一个字符不能是数字
23 // 同上
*** // 标识符不能包含星号
a+b // 标识符不能包含加号
-d // 标识符不能包含减号或连词线
中文是合法的标识符,可以用作变量名。
var 临时变量 = 1;
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。
另外,还有三个词虽然不是保留字,但是因为具有特别含义,也不应该用作标识符:Infinity
、NaN
、undefined
。
注释
源码中被JavaScript引擎忽略的部分就叫做注释,它的作用是对代码进行解释。Javascript提供两种注释:一种是单行注释,用//起头;另一种是多行注释,放在/* 和 */之间。
// 这是单行注释
/*
这是
多行
注释
*/
此外,由于历史上JavaScript兼容HTML代码的注释,所以<!--
和-->
也被视为单行注释。
x = 1; <!-- x = 2;
--> x = 3;
上面代码中,只有x = 1
会执行,其他的部分都被注释掉了。
需要注意的是,-->
只有在行首,才会被当成单行注释,否则就是一个运算符。
function countdown(n) {
while (n --> 0) console.log(n);
}
countdown(3)
// 2
// 1
// 0
上面代码中,n --> 0
实际上会当作n-- > 0
,因此输出2、1、0。
区块
JavaScript使用大括号,将多个相关的语句组合在一起,称为“区块”(block)。
与大多数编程语言不一样,JavaScript的区块不构成单独的作用域(scope)。也就是说,区块中的变量与区块外的变量,属于同一个作用域。
{
var a = 1;
}
a // 1
上面代码在区块内部,声明并赋值了变量a
,然后在区块外部,变量a
依然有效,这说明区块不构成单独的作用域,与不使用区块的情况没有任何区别。所以,单独使用的区块在JavaScript中意义不大,很少出现。区块往往用来构成其他更复杂的语法结构,比如for
、if
、while
、function
等。
JavaScript 数据类型
概述
JavaScript 语言的每一个值,都属于某一种数据类型。JavaScript 的数据类型,共有六种。(ES6 又新增了第七种 Symbol 类型的值)
- 数值(number):整数和小数(比如1和3.14)
- 字符串(string):字符组成的文本(比如"Hello World")
- 布尔值(boolean):
true
(真)和false
(假)两个特定值 undefined
:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值null
:表示无值,即此处的值就是“无”的状态。- 对象(object):各种值组成的集合
通常,我们将数值、字符串、布尔值称为原始类型(primitive type)的值,即它们是最基本的数据类型,不能再细分了。而将对象称为合成类型(complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。至于undefined
和null
,一般将它们看成两个特殊值。
对象又可以分成三个子类型。
- 狭义的对象(object)
- 数组(array)
- 函数(function)
typeof运算符
JavaScript有三种方法,可以确定一个值到底是什么类型。
typeof
运算符instanceof
运算符Object.prototype.toString
方法
instanceof
运算符和Object.prototype.toString
方法,将在后文相关章节介绍。这里着重介绍typeof
运算符。
typeof
运算符可以返回一个值的数据类型,可能有以下结果。
(1)原始类型
数值、字符串、布尔值分别返回number
、string
、boolean
。
typeof 123 // "number"
typeof '123' // "string"
typeof false // "boolean"
(2)函数
函数返回function
。
function f() {}
typeof f
// "function"
(3)undefined
undefined
返回undefined
。
typeof undefined
// "undefined"
利用这一点,typeof可以用来检查一个没有声明的变量,而不报错。
v
// ReferenceError: v is not defined
typeof v
// "undefined"
上面代码中,变量v
没有用var
命令声明,直接使用就会报错。但是,放在typeof
后面,就不报错了,而是返回undefined
。
实际编程中,这个特点通常用在判断语句。
// 错误的写法
if (v) {
// ...
}
// ReferenceError: v is not defined
// 正确的写法
if (typeof v === "undefined") {
// ...
}
(4)其他
除此以外,其他情况都返回object
。
typeof window // "object"
typeof {} // "object"
typeof [] // "object"
typeof null // "object"
从上面代码可以看到,空数组([]
)的类型也是object
,这表示在JavaScript内部,数组本质上只是一种特殊的对象。
既然typeof
对数组(array)和对象(object)的显示结果都是object
,那么怎么区分它们呢?instanceof
运算符可以做到。
var o = {};
var a = [];
o instanceof Array // false
a instanceof Array // true
instanceof
后续讲解。
布尔值
布尔值代表“真”和“假”两个状态。“真”用关键字true
表示,“假”用关键字false
表示。布尔值只有这两个值。
下列运算符会返回布尔值:
- 两元逻辑运算符:
&&
(And),||
(Or) - 前置逻辑运算符:
!
(Not) - 相等运算符:
===
,!==
,==
,!=
- 比较运算符:
>
,>=
,<
,<=
如果JavaScript预期某个位置应该是布尔值,会将该位置上现有的值自动转为布尔值。转换规则是除了下面六个值被转为false
,其他值都视为true
。
undefined
null
false
0
NaN
""
或''
(空字符串)
布尔值往往用于程序流程的控制,请看一个例子。
if ('') {
console.log(true);
}
// 没有任何输出
上面代码的if
命令后面的判断条件,预期应该是一个布尔值,所以JavaScript自动将空字符串,转为布尔值false
,导致程序不会进入代码块,所以没有任何输出。
需要特别注意的是,空数组([]
)和空对象({}
)对应的布尔值,都是true
。
if ([]) {
console.log(true);
}
// true
if ({}) {
console.log(true);
}
// true
更多关于数据类型转换的介绍,参见《数据类型转换》一节。
运算符
JavaScript中运算符主要用于连接简单表达式,组成一个复杂的表达式。常见的有算数表达式、比较表达式、逻辑表达式、赋值表达式等,也有单目运算符,指操作原始表达式。大多数运算符都由标点符号组成(+、>=、!),也有关键字表示的运算符,如typeof、delete、instanceof等。
一些运算符可以作用于任何数据类型(typeof),但大部分操作符希望操作数是特定的类型,而且大部分操作符会计算出(我们也常说返回)一个特定类型的值(typeof返回的全是string)。在JavaScript中运算符通常会根据需要对操作数进行类型转换,乘法操作符希望操作数是数字,但是 "3" * "5"
也是合法的,JavaScript会自动将其转换为数字计算,返回Number 15。
有些操作符对不同的数据类型有不同的含义,比如 +
- 在两个操作数都是数字的时候,会做加法运算
- 两个参数都是字符串或在有一个参数是字符串的情况下会把另外一个参数转换为字符串做字符串拼接
- 在参数有对象的情况下会调用其valueOf或toString
- 在只有一个字符串参数的时候会尝试将其转换为数字
- 在只有一个数字参数的时候返回其正数值
console.log(2+4);//6
console.log("2"+"4");//"24"
console.log(2+"4");//"24"
console.log(2+new Date());//"2Mon Jan 20 2014 17:15:01 GMT+0800 (China Standard Time)"
console.log(+"4");//4
远算符类型
算数运算符
- 加法运算符(Addition):x + y
- 减法运算符(Subtraction): x - y
- 乘法运算符(Multiplication): x * y
- 除法运算符(Division):x / y
- 余数运算符(Remainder):x % y
- 自增运算符(Increment):++x 或者 x++
- 自减运算符(Decrement):--x 或者 x--
- 求负运算符(Negate):-x
- 数值运算符(Convert to number): +x
赋值运算符
赋值运算符用于给变量赋值,最常见的赋值运算符,当然就是等号,表达式x=y
表示将y赋值给x。除此之外,JavaScript还提供其他11个赋值运算符。
x += y // 等同于 x = x + y
x -= y // 等同于 x = x - y
x *= y // 等同于 x = x * y
x /= y // 等同于 x = x / y
x %= y // 等同于 x = x % y
x >>= y // 等同于 x = x >> y
x <<= y // 等同于 x = x << y
x >>>= y // 等同于 x = x >>> y
x &= y // 等同于 x = x & y
x |= y // 等同于 x = x | y
x ^= y // 等同于 x = x ^ y
比较运算符
比较运算符比较两个值,然后返回一个布尔值,表示是否满足比较条件。JavaScript提供了8个比较运算符。
==
相等===
严格相等!=
不相等!==
严格不相等<
小于<=
小于或等于>
大于>=
大于或等于
布尔运算符
!
取反运算符&&
且运算符||
或运算符condition? true case : false case
三元条件运算符
位运算符
- 或运算(or):符号为
|
,表示两个二进制位中有一个为1,则结果为1,否则为0。 - 与运算(and):符号为
&
,表示两个二进制位都为1,则结果为1,否则为0。 - 否运算(not):符号为
~
,表示将一个二进制位变成相反值。 - 异或运算(xor):符号为
ˆ
,表示两个二进制位中有且仅有一个为1时,结果为1,否则为0。 - 左移运算(left shift):符号为
<<
- 右移运算(right shift):符号为
>>
- 带符号位的右移运算(zero filled right shift):符号为
>>>
其它
小括号
在JavaScript中,圆括号是一种运算符,它有两种用法:如果把表达式放在圆括号之中,作用是求值;如果跟在函数的后面,作用是调用函数。
把表达式放在圆括号之中,将返回表达式的值。
void
void运算符的作用是执行一个表达式,然后返回undefined。
逗号运算符
逗号运算符用于对两个表达式求值,并返回后一个表达式的值。
运算符优先级与结合性
优先级什么意思大家都清楚,结合性是指多个具有同样优先级的运算符表达式中的运算顺序。有的运算符是左结合的,即运算从左到右执行,下面两个运算是一样的
w = x + y + z;
w = (x + y) + z;
有的运算符是右结合的
w = x = y = z;
w = (x = (y = z));
w = a: b: c ? d : e? f : g;
w = a? b : (c? d: (e? f : g));
运算符的优先级《JavaScript权威指南》中有个表阐述的很好(我去掉了位运算部分),其中R/L代表结合性是右结合还是左结合,num->num表示操作符期望的数据类型和计算结果类型,lval指左值
运算符 | 操作 | 结合性 | 类型 |
---|---|---|---|
++ | 自增 | R | lval->num |
-- | 自减 | R | lval->num |
- | 求反 | R | num->num |
+(一个操作数) | 转换为数字 | R | num->num |
~ | 按位求反 | R | int->int |
! | 逻辑非 | R | bool->bool |
delete | 删除属性 | R | lval->bool |
typeof | 检测数据类型 | R | any->str |
void | 返回undefined | R | any->undefined |
|
|||
*、/、% | 乘、除、求余 | L | num,num->num |
|
|||
+、- | 加、减 | L | num,num->num |
+ | 字符串拼接 | L | str,str->str |
<、<=、>、>= | 数字大小或字母表顺序 | L | num/str,num/str->bool |
instanceof | 对象类型 | L | obj,function->bool |
in | 测试属性是否存在 | L | str,obj->bool |
|
|||
== | 判断相等 | L | any,any->bool |
!= | 判断不等 | L | any,any->bool |
=== | 判断恒等 | L | any,any->bool |
!== | 判断非恒等 | L | any,any->bool |
|
|||
&& | 逻辑与 | L | any,any->any |
|| | 逻辑或 | L | any,any->any |
?: | 条件运算符 | R | bool,any,any->any |
=赋值 *=、/=、+=、-= | 赋值 运算且赋值 | R | lval,any->any |
, | 忽略第一个操作数,返回第二个操作数 | L | any,any->any |
有几个我们需要注意的地方
typeof的优先级相当的高,比加减乘除神马的都高,所以虽然是操作符,在在复杂表达式的时候我们还是习惯加括号,看个例子
typeof 2*3;//NaN
typeof (2*3);//"number"
typeof 2+3;// "number3"
++
、--
是右结合的操作符(优先级最高的几个都是右结合),而且比加减乘除优先级高。同时自增、自减运算符的运算数得是左值(可以放在赋值符号左边的值),而不能是常数4++; //ReferenceError: Invalid left-hand side expression in postfix operation
var a=0,b=0;
a+++b;//0
a;//1,++优先级比+高,所以相当于(a++)+b
b;//0
赋值运算符的优先级相当的低
a = b == c; //等同于a = (b==c)
逻辑非
!
也在优先级队列的前端,比加减乘除高,但逻辑与、逻辑或优先级很低,不如加减乘除!2*0; //0, 等价于(!2)*0
一个关于逻辑运算符的有意思地方是其“短路”功能,相信大家都有所了解,但有些题目不那么单纯,会结合表达式计算值来考察
1 && 3;
1 && "foo" || 0;
1 || "foo" && 0
了解了逻辑运算符的“短路”特点,在知道原始表达式的“返回值”就是本身,题目就很简单了
相等
我们知道可以使用==
或===
判断两个值的相等性,其中区别相信大家清楚,===
是严格意义的相等,只需注意NaN和NaN不等就行了。而使用==
的时候,javascript会帮我们做类型转换,造成一些匪夷所思的结果,那么使用==
的时候会在哪些情况下做类型转换,又会换成什么样子?
- 如果两个值类型相同,则执行严格相等的运算
- 如果两个值的类型不同
- 如果一个是null,一个是undefined,那么相等
- 如果一个是数字,一个是字符串,先将字符串转为数字,然后比较
- 如果一个值是true/false则将其转为1/0比较
- 如果一个值是对象,一个是数字或字符串,则尝试使用valueOf和toString转换后比较
- 其它就不相等了
null==undefined;
NaN==NaN
"1"==true
JavaScript 的一些基础知识的更多相关文章
- javascript之正则表达式基础知识小结
javascript之正则表达式基础知识小结,对于学习正则表达式的朋友是个不错的基础入门资料. 元字符 ^ $ . * + ? = ! : | \ / ( ) [ ] { } 在使用这些符号时需要 ...
- ArcGIS API for JavaScript开发初探——基础知识
1.前言 在ArcGIS Web API开发体系中一共有四大类,分别为: ArcGIS API for Flex ArcGIS API for JavaScript ArcGIS API for RE ...
- javascript DOM 操作基础知识小结
经常用到javascript对dom,喜欢这方便的朋友也很多,要想更好的对dom进行操作,这些基础一定要知道的. DOM添加元素,使用节点属性 <!DOCTYPE html PUBLIC ...
- JavaScript进阶【三】JavaScript面向对象的基础知识复习
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JavaScript简介及基础知识(1)
1.JavaScript是什么—它是个脚本语言,需要宿主文件,它的宿主文件是html文件. Javascript是一种脚本语言,比HTML要复杂.不过即便你先前不懂编程,也不用担心,因为Javascr ...
- javascript 函数的基础知识
1. Why JavaScript functions always return a value? I'm taking a course in JavaScript programming, an ...
- javascript——对象的基础知识
一.javascript作为脚本语言可以完成以下任务: 操纵浏览器对象,如窗口的打开与关闭: 操纵Dom树: 通过XMLHttpRequest对象与服务器端进行异步通信: XML编程,借助于Activ ...
- javaScript 必会基础知识
1.JavaScript是一种浏览器解析的轻量级脚本语言. 2.html.jsp等内部js代码写在<script></script>之间:外部js文件中书写js代码不能有< ...
- javascript中DOM基础知识介绍
1.1. 基本概念 1.1.1. DOM DOM Document Object Model 文档对象模型 就是把HTML文档模型化,当作对象来处理 DOM提供的一系列属性和方法可以 ...
随机推荐
- angular动态绑定样式以及改变UI框架样式的方法
一:angular动态绑定样式 举个栗子: <tr *ngFor="let dataTr of tableData;let i = index" [formGroupName ...
- 关于Django中JsonResponse返回中文字典编码错误的解决方案
解决方案:JsonResponse(data, json_dumps_params={'ensure_ascii':False}) ! data是需要渲染的字典 def master(request) ...
- 用Jquery控制元素的上下移动 实现排序功能
在页面上,控制元素上下移动,进行排序是我们比较常用的功能,今天我用jQuery 写个 简单方便,功能齐全的实现方式. 话不多说,直接上代码,下面是基础的引入jq和html元素部分: <scrip ...
- 高并发下,HashMap会产生哪些问题?
HashMap在高并发环境下会产生的问题 HashMap其实并不是线程安全的,在高并发的情况下,会产生并发引起的问题: 比如: HashMap死循环,造成CPU100%负载 触发fail-fast 下 ...
- tp5.1路由报错No input file specified.
问题: 按照官方教安装了框架,打开首页没问题,可是安装教程路由规则打开 "http://127.0.0.1/hello/2" 时, 却报错误 "No input fil ...
- PHP实现openSug.js参数调试
这是一款利PHP对百度搜索下拉框提示免费代码实现参数配置调试的程序源代码. 由想要对网站进行搜索下拉调试的站长朋友们进行方便.快速的效果演示,具体参考下面的PHP代码. 如何使用? 请新建一份PHP文 ...
- CRM2Stark组件
CRM stark组件 开启新项目:CRM 再创建一个应用app02(python manage.py startapp app02 或者是工具栏:run...task:执行startapp app0 ...
- Codeforces Round #482 (Div. 2) : Kuro and GCD and XOR and SUM (寻找最大异或值)
题目链接:http://codeforces.com/contest/979/problem/D 参考大神博客:https://www.cnblogs.com/kickit/p/9046953.htm ...
- CSS基础part2
CSS属性操作-文本 文本颜色 <head> <style> p{ /*color:#8B5742 ;色码表*/ color: RGBA(255,0,0,0.5); /*调色, ...
- 20145234黄斐《Java程序设计》第一周学习总结
教材学习内容总结 1.java是SUN公司推出的面相网络的编程语言,当时取名Oak,后改名Java. 2.Java三大平台分别为:Java SE.Java EE与Java ME. 3.Java不仅是程 ...