JavaScript(一)基本语法、常见语句、操作符

一、JS概述

关于JavaScript的历史,语言特点,略。

二、JavaScript的组成

JavaScript是ECMAScript、文档对象模型(document object model:DOM)、浏览器对象模型(brower object model:BOM)由三部分构成,其核心是ECMAScript,它描述了该语言的语法和基本对象;DOM 描述了处理网页内容的方法和接口,通过 DOM,可以访问所有的 HTML 元素,连同它们所包含的文本和属性,可以对其中的内容进行修改和删除,同时也可以创建新的元素;BOM 描述了与浏览器进行交互的方法和接口,BOM提供了独立于内容而与浏览器窗口进行交互的对象,例如可以移动,调整浏览器大小的window对象,可以用于导航的location对象与history对象,可以获取浏览器,操作系统与用户屏幕信息的navigator与screen对象,可以使用document作为访问HTML文档的入口,管理框架的frames对象等。

JavaScript的组成.jpg

三、JavaScript的引入方式

3.1外部引入

在<script></script>标签里面src=“ ”;中添加链接

<script type="text/javascript" src="yuanmi.js">
        // 如果链接了外部JS文件,script标签里面的JS代码就不执行了
        // 此处不能加JS代码
</script>

3.2内部引入

在script标签内添加

<script type="text/javascript">
    <!-- script标签可以有多个,按顺序执行 -->
        console.log("你好!")
</script>

四、基本概念

1、ECMAscript中的一切(变量、函数名,操作符)都区分大小写

2、标志符(标识符(identifier)指的是用来识别各种值的合法名称。最常见的标识符就是变量名,以及后面要提到的函数名):第一个字符必须是一个字母,下划线、美元符号。其他字符可以是字符、下划线。美元符号、或者是数字

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。

3、注释

  • 单行注释://
  • 多行注释:/* */

4、变量:ECMAscript的变量是松散型的,所谓松散型就是可以用来保存任何类型的数据、定义时要用var操作符,如果在函数中使用var定义一个变量,那么这个变量在函数退出 后就会被销毁,如果省略var,那么这个变量就成为全局变量,可以在函数外的任何一个地方被访问到,但是,不推荐这么使用。

  • 变量是对值的具名引用,变量就是为“值”起名,然后引用这个名字,就等同于引用这个值
  • 如果只是声明变量而没有赋值,则该变量的值是undefined
  • 变量的类型没有限制,变量可以随时更改类型。
  • 第二次声明的时候还进行了赋值,则会覆盖掉前面的值。
  • 变量提升:JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升。表示变量已声明,但还未赋值

五、数据类型

JavaScript 语言的每一个值,都属于某一种数据类型。JavaScript 的数据类型,共有六种。(ES6 又新增了第七种 Symbol 类型的值,本文不涉及。)

  • 数值(number):整数和小数(比如1和3.14)
  • 字符串(string):文本(比如Hello World)。
  • 布尔值(boolean):表示真伪的两个特殊值,即true(真)和false(假)
  • undefined:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值
  • null:表示空值,即此处的值为空。
  • 对象(object):各种值组成的集合。

通常,数值、字符串、布尔值这三种类型,合称为原始类型(primitive type)的值,即它们是最基本的数据类型,不能再细分了。对象则称为合成类型(complex type)的值,因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。至于undefined和null,一般将它们看成两个特殊值。

5.1 undefined

  • 1、定义一个变量,但是没有初始化,会得到undefined
  • 2、变量未定义,会得到undefined
  • 3、函数中return不带任何返回值时,函数停止执行会返回undefined
  • 4、函数参数arguments,没有传递值的命名参数将自动被赋予undefined
  • 5、对象没有赋值的属性var o = new Object(); o.p // undefined

5.2 Null

  • null是只有一个值得数据类型,这个特殊值是null
  • null值表示一个空对象指针,如果保存对象的变量还没有真正的保存对象,就应该明确的让该变量保存null值
    特殊情况:
  • alert(null == undefined)//true
  • alert(null === undefined)//false

5.3 Boolean
该类型有2个字面量值true和false,经常用在流程控制语句和选择判断语句,
常见false值,除了false值都基本都是true

  • 1.数字0、
  • 2.NaN、
  • 3.“ ”,空字符串
  • 4.false
  • 5.undefined
  • 6.null
    下列运算符会返回布尔值:
  • 前置逻辑运算符: ! (Not)
  • 相等运算符:===,!==,==,!=
  • 比较运算符:>,>=,<,<=

5.4 Number

  • 1、浮点数:所谓浮点数,就是该数值中必须包含一个小数点,且小数点后面至少有一位数字,由于保存浮点数的内存空间是保存整数的2倍,因此,如果小数点后面没有任何数字,或者本身就是一个整数(1.0),那么该值会被转化成整数,但是浮点数计算会产生四舍五入误差的问题。

  • 2、数值范围:由于内存的限制,ECMAScript 并不能保存世界上所有的数值。ECMAScript 能够表示的最小数值保 存在 Number.MIN_VALUE 中——在大多数浏览器中,这个值是 5e-324;能够表示的最大数值保存在 Number.MAX_VALUE 中——在大多数浏览器中,这个值是 1.7976931348623157e+308。如果某次计算的 结果得到了一个超出 JavaScript 数值范围的值,那么这个数值将被自动转换成特殊的 Infinity 值。具 体来说,如果这个数值是负数,则会被转换成-Infinity(负无穷),如果这个数值是正数,则会被转 换成 Infinity(正无穷)。

  • isFinite():这个函数在参数位于最小和最大值之间会返回true

3、NaN
这个数值表示一个本来要返回数值的操作数未返回的情况(这样不会抛出错误)
任何设计NAN的操作都会返回NaN,其次,NaN与任何值都不相等,包括NaN本身
isNaN():任何不能被转化成数值的值都会导致这个函数返回true

  • 数值转化
    Number():可以转化任何类型数据
    parseInt():专门用于把字符串转化成整数
    parseFloat():专门用于把字符串转化成浮点数

5.5 String
多个字符的有序序列,双引号和单引号引起来的都是字符串

转化成字符串

  • toString(),String()
    两者区别:
    1、除了null和undefined值,任何值都有toString()
    2、toSring()接受一个参数,表示进制
    3、String()能够将任何类型的值都转换成字符串

  • toString()规则:值如果有toString,则调用该方法,如果值是null,则返回“null”,如果值是undefined,返回‘undefined’

六、检测数值类型

typeof()

typeof()是用来检测给定变量的数据类型,对一种值使用typeof操作符可能返回下列某个字符串
‘undefined’:这个值未定义
‘boolean’:这个值是布尔类型
‘string’:这个值是字符串
‘number’:这个值是数值
‘object’:这个值是对象或者null
‘function’:这个值是函数

typeof操作符用来区分函数和其他对象是有必要的

instanceof运算符
Object.prototype.toString方法

七、语句

7.1 条件语句

if语句

// if结构先判断一个表达式的布尔值,然后根据布尔值的真伪,执行不同的语句
if (布尔值){
    语句;
}

// 或者
if (布尔值) 语句;

if else语句

if (布尔值) {
  // 满足条件时,执行的语句
} else {
  // 不满足条件时,执行的语句
}

if ...else 语句

if (m === 0) {
  // ...
} else if (m === 1) {
  // ...
} else if (m === 2) {
  // ...
} else {
  // ...
}

switch语句

// 选择执行相应的case。如果所有case都不符合,则执行最后的default部分
// switch语句内部采用的是“严格相等运算符”
switch (x) {
  case 1:
    console.log('x 等于1');
    break;
  case 2:
    console.log('x 等于2');
    break;
  default:
    console.log('x 等于其他值');
}

三元运算符 ?:

// 如果“条件”为true,则返回“表达式1”的值,否则返回“表达式2”的值。
(条件) ? 表达式1 : 表达式2
't' ? 'hello' : 'world' // "hello"
0 ? 'hello' : 'world' // "world"

7.2 循环语句

while循环

// While语句包括一个循环条件和一段代码块,只要条件为真,就不断循环执行代码块。
while (条件) {
  语句;
}
// 或者
while (条件) 语句;

for 循环

// 初始化表达式(initialize):确定循环变量的初始值,只在循环开始时执行一次。
// 条件表达式(test):每轮循环开始时,都要执行这个条件表达式,只有值为真,才继续进行循环。
// 递增表达式(increment):每轮循环的最后一个操作,通常用来递增循环变量。
for (初始化表达式; 条件; 递增表达式) {
  语句
}
for语句的三个部分(initialize、test、increment),可以省略任何一个,也可以全部省略。

for ( ; ; ){
  console.log('Hello World');
}
上面代码省略了for语句表达式的三个部分,结果就导致了一个无限循环。

do while语句:至少执行一次

// do...while循环与while循环类似,唯一的区别就是先运行一次循环体,然后判断循环条件。
// 不管条件是否为真,do...while循环至少运行一次,这是这种结构最大的特点。另外,while语句后面的分号注意不要省略。
do
  语句
while (条件);

// 或者
do {
  语句
} while (条件);

break 语句和 continue 语句
break语句用于跳出代码块或循环。
continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环

for (var i = 0; i < 5; i++) {
  console.log(i);
  if (i === 3)
    break;
}
// 0
// 1
// 2
// 3
// 上面代码执行到i等于3,就会跳出循环

var i = 0;

while (i < 100){
  i++;
  if (i % 2 === 0) continue;
  console.log('i 当前为:' + i);
}
// 上面代码只有在i为奇数时,才会输出i的值。如果i为偶数,则直接进入下一轮循环

标签(label)
JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置.
标签可以是任意的标识符,但不能是保留字,语句部分可以是任意语句。
标签通常与break语句和continue语句配合使用,跳出特定的循环。

top:
  for (var i = 0; i < 3; i++){
    for (var j = 0; j < 3; j++){
      if (i === 1 && j === 1) break top;
      console.log('i=' + i + ', j=' + j);
    }
  }
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// break命令后面加上了top标签(注意,top不用加引号),满足条件时,直接跳出双层循环。如果break语句后面不使用标签,则只能跳出内层循环,进入下一次的外层循环。

top:
  for (var i = 0; i < 3; i++){
    for (var j = 0; j < 3; j++){
      if (i === 1 && j === 1) continue top;
      console.log('i=' + i + ', j=' + j);
    }
  }
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// i=2, j=0
// i=2, j=1
// i=2, j=2
// continue命令后面有一个标签名,满足条件时,会跳过当前循环,直接进入下一轮外层循环。如果continue语句后面不使用标签,则只能进入下一轮的内层循环。

八、操作符

++ : 自增

++
// 运算子首先转为数值,然后加上1或者减去1。它们会修改原始变量
// 自增和自减运算符是仅有的两个具有副作用的运算符,其他运算符都不会改变变量的值
var x = 1;
++x // 2
x // 2

-- : 自减

var x = 2;
--x // 1
x // 1
// 自增和自减运算符有一个需要注意的地方,
// 就是放在变量之后,会先返回变量操作前的值,再进行自增/自减操作;
// 放在变量之前,会先进行自增/自减操作,再返回变量操作后的值
var x = 1;
var y = 1;
// x是先返回当前值,然后自增,所以得到1
x++ // 1
++y // 2
// y是先自增,然后返回新的值,所以得到2

+ :加号操作符

// 1. 用来求两个数值的和
// 2. 两个字符串相加,这时加法运算符会变成连接运算符,返回一个新的字符串,将两个原字符串连接在一起
// 3. 一个运算子是字符串,另一个运算子是非字符串,这时非字符串会转成字符串,再连接在一起
'3' + 4 + 5 // "345"
3 + 4 + '5' // "75"
// 4. 重载:加法运算符是在运行时决定,到底是执行相加,还是执行连接。也就是说,运算子的不同,导致了不同的语法行为,这种现象称为“重载”(overload)
// 5. 对象的相加
//    如果运算子是对象,必须先转成原始类型的值,然后再相加
//    对象转成原始类型的值,首先,自动调用对象的valueOf方法,一般来说,
//    对象的valueOf方法总是返回对象自身,这时再自动调用对象的toString方法,将其转为字符串,知道了这个就可以自己定义valueOf方法或toString方法,得到想要的结果
var obj = { p: 1 };
obj.valueOf().toString() // "[object Object]"

var obj = {
  valueOf: function () {
    return 1;
  }
};

obj + 2 // 3
//   如果运算子是一个Date对象的实例,那么会优先执行toString方法
var obj = new Date();
obj.valueOf = function () { return 1 };
obj.toString = function () { return 'hello' };

obj + 2 // "hello2"

-:主要用来表示负数

// 具有将一个值转为数值的功能,只不过得到的值正负相反
var x = 1;
-x // -1
-(-x) // 1

** : 指数运算符

// 指数运算符(**)完成指数运算,前一个运算子是底数,后一个运算子是指数。
2 ** 4 // 16
// 指数运算符是右结合,而不是左结合。即多个指数运算符连用时,先进行最右边的计算
2 ** 3 ** 2
// 512

乘性操作符

乘法:*
除法: /
求模:%
// 余数运算符(%)返回前一个运算子被后一个运算子除,所得的余数
// 运算结果的正负号由第一个运算子的正负号决定。
// 为了得到负数的正确余数值,可以先使用绝对值函数
-1 % 2 // -1
1 % -2 // 1
// 错误的写法
function isOdd(n) {
  return n % 2 === 1;
}
isOdd(-5) // false
isOdd(-4) // false

// 正确的写法
function isOdd(n) {
  return Math.abs(n % 2) === 1;
}
isOdd(-5) // true
isOdd(-4) // false

===: 全等

// 如果两个值的类型不同,直接返回false
1 === "1" // false
// 同一类型的原始类型的值(数值、字符串、布尔值)比较时,值相同就返回true,值不同就返回false
1 === 0x1 // true
//NaN与任何值都不相等(包括自身)。另外,正0等于负0
NaN === NaN  // false
+0 === -0 // true
// 复合类型值: 两个复合类型(对象、数组、函数)的数据比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个地址
{} === {} // false
[] === [] // false
(function () {} === function () {}) // false
// 如果两个变量引用同一个对象,则它们相等。
var v1 = {};
var v2 = v1;
v1 === v2 // true
//对于两个对象的比较,严格相等运算符比较的是地址,而大于或小于运算符比较的是值。
//undefined和null与自身严格相等
undefined === undefined // true
null === null // true
var v1;
var v2;
v1 === v2 // true

!==:不全等

// 先求严格相等运算符的结果,然后返回相反值
1 !== '1' // true
// 等同于
!(1 === '1')

==:相等

// 1、原始类型的值会转换成数值再进行比较
'1' == true  // true
// 等同于 Number('1') === Number(true)
// 等同于 1 === 
'true' == true // false
// 等同于 Number('true') === Number(true)
// 等同于 NaN === 1
// 2、对象(这里指广义的对象,包括数组和函数)与原始类型的值比较时,对象转换成原始类型的值,再进行比较。
// 对象与数值比较时,对象转为数值
[1] == 1 // true
// 等同于 Number([1]) == 1

// 对象与字符串比较时,对象转为字符串
[1] == '1' // true
// 等同于 String([1]) == '1'
[1, 2] == '1,2' // true
// 等同于 String([1, 2]) == '1,2'

// 对象与布尔值比较时,两边都转为数值
[1] == true // true
// 等同于 Number([1]) == Number(true)
[2] == true // false
// 等同于 Number([2]) == Number(true)

// 3、undefined和null与其他类型的值比较时,结果都为false,它们互相比较时结果为true
false == null // false
false == undefined // false

0 == null // false
0 == undefined // false

undefined == null // true

// 4、相等运算符的缺点
// 相等运算符隐藏的类型转换,会带来一些违反直觉的结果
0 == ''             // true
0 == '0'            // true

2 == true           // false
2 == false          // false

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

!=: 不等运算符

// 它的算法就是先求相等运算符的结果,然后返回相反值
1 != '1' // false

// 等同于
!(1 == '1')

>: 大于

//1、是否都是字符串,如果是的,就按照字典顺序比较(实际上是比较 Unicode 码点)
     'cat' > 'catalog' // false
//2、如果不是字符串,就会将两个运算子都转成数值,再比较数值的大小
      5 > '4' // true
      // 等同于 5 > Number('4')
      // 即 5 > 4

      true > false // true
      // 等同于 Number(true) > Number(false)
      // 即 1 > 0

      2 > true // true
      // 等同于 2 > Number(true)
      // 即 2 > 1
// 3、这里需要注意与NaN的比较。任何值(包括NaN本身)与NaN比较,返回的都是false。
     1 > NaN // false
     1 <= NaN // false
     '1' > NaN // false
     '1' <= NaN // false
     NaN > NaN // false
     NaN <= NaN // false
// 4、如果运算子是对象,会转为原始类型的值,再进行比较。
     [2] > [1] // true
     // 等同于 [2].valueOf().toString() > [1].valueOf().toString()
     // 即 '2' > '1'

    [2] > [11] // true
    // 等同于 [2].valueOf().toString() > [11].valueOf().toString()
    // 即 '2' > '11'

    { x: 2 } >= { x: 1 } // true
    // 等同于 { x: 2 }.valueOf().toString() >= { x: 1 }.valueOf().toString()
    // 即 '[object Object]' >= '[object Object]'
小于:<
大于等于:>=
小于等于:<=

= : 赋值操作符

// 将 1 赋值给变量 x
var x = 1;
// 将变量 y 的值赋值给变量 x
var 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

布尔操作符
! :逻辑非

// 取反运算符是一个感叹号,用于将布尔值变为相反值,即true变成false,false变成true
!true // false
!false // true
!undefined // true
!null // true
!0 // true
!NaN // true
!"" // true
!54 // false
!'hello' // false
![] // false
!{} // false

&&:且运算符

// 如果第一个运算子的布尔值为true,则返回第二个运算子的值(注意是值,不是布尔值);
// 如果第一个运算子的布尔值为false,则直接返回第一个运算子的值,且不再对第二个运算子求值。
't' && 'f' // "f"
't' && (1 + 2) // 3
'' && 'f' // ""
'' && '' // ""

var x = 1;
(1 - 1) && ( x += 1) // 0
x // 1
// 且运算符可以多个连用,这时返回第一个布尔值为false的表达式的值。如果所有表达式的布尔值都为true,则返回最后一个表达式的值
true && 'foo' && '' && 4 && 'foo' && true
// ''
1 && 2 && 3
// 3

||: 或运算符

// 如果第一个运算子的布尔值为true,则返回第一个运算子的值,且不再对第二个运算子求值;
// 如果第一个运算子的布尔值为false,则返回第二个运算子的值
't' || '' // "t"
't' || 'f' // "t"
// 或运算符可以多个连用,这时返回第一个布尔值为true的表达式的值。如果所有表达式都为false,则返回最后一个表达式的值
false || 0 || '' || 4 || 'foo' || true
// 4
false || 0 || ''
// ''
function saveText(text) {
  text = text || '';
  // ...
}

// 或者写成
saveText(this.text || '')

本文参考:JavaScript 教程

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容