目录
前言
浏览器执行JS简介
JS的组成
ECMAScript
JS的书写位置
变量
数据类型
运算符
流程控制
数组
函数
作用域
计算机语言分为:机器语言,汇编语言,高级语言三类;
计算机最终所执行的都是机器语言,它是由'0'和'1'组成的二进制数;
汇编语言和机器语言本质是相同的,都是直接对硬件操作,只不过指令采用了英文缩写的标识符,容易识别和记忆;
高级语言主要是相对于低级语言而言,它并不是特指某一种具体的语言,而是包含了很多编程语言,常用的有C语言/C++/C#/Java/python/JavaScript;
高级语言所编写的程序不能直接被计算机识别,必须经过转换才能被执行,中间需要有一个翻译器。这个翻译器在JavaScript就可以是浏览器的解析器,如谷歌的V8
编程语言有很强的逻辑和行为能力,发出的指令是主动的;
标记语言不用于向计算机发出指令,常用于格式化和链接,标记语言的存在是用来被读取的,它是被动的;
浏览器分为两部分:渲染引擎和JS引擎;
渲染引擎:用来解析HTML与CSS,俗称内核,如谷歌浏览器的blink,老版本的webkit;
JS引擎:也称为JS解释器,用来读取网页中的JavaScript代码,对其处理后运行,如谷歌浏览器的V8;
浏览器本身并不会执行JS代码,而是通过内置JavaScript引擎(解释器)来执行JS代码。JS引擎执行代码时逐行解释每一句源码(转换为机器语言),然后由计算机去执行,所以JavaScript语言归为脚本语言,会逐行解释执行。
JavaScript定性:是一种运行在客户端的脚本语言(脚本语言是指不需要编译,运行过程中由js解释器--js引擎逐行来进行解释并执行);可以用作表单动态校验(密码强度检测、网页特效、服务器开发、桌面程序、APP、控制硬件-物联网、游戏开发)
由三部分组成:ECMAScript(JavaScript语法)、DOM(页面文档对象模型)、BOM(浏览器对象模型)
它是由ECMA国际进行标准化的一门编程语言,规定了JS的编程语法和基础核心知识,是所有浏览器厂商共同遵守的一套JS语法工业标准。
下面的是ECMAScript语法规范
分为行内、内嵌和外部三种方式;
行内式:可将单行或少量JS代码写在HTML标签的事件属性中(以on开头的属性),如onclick ;
查 询
内嵌式:将多行JS代码写到
外部式:将大段js代码独立于HTML页面之外,引用外部JS文件的script标签中间不可以写代码~
变量是程序在内存中申请的一块用来存放数据的空间。
var name; // 声明变量
name = '张三' // 赋值
也可以直接一步对变量初始化:
var name = '张三'
可同时声明多个变量,变量名之间用英文逗号隔开:
var name='张三', sex= '男', age = 12;
声明变量的特殊情况:
情况 | 说明 | 结果 |
var age; console.log(age) | 只声明,不赋值 | undefined |
console.log(age) | 不声明,不赋值,直接使用 | 报错 |
age=10;console.log(age); | 不声明,只赋值 | 10 |
ps:第三种方式,会变成全局变量,也有问题,不提倡使用
由字母(A-Za-z)、数字(0-9)、下划线、美元符号($)组成 ;
JavaScript是一种弱类型或者说动态语言,这意味着,利用var声明的变量类型,在程序运行过程中,数据类型会自动确定; 同时这也意味着,相同的变量可用作不同的类型:
var x=6; // x为数字
var x="张三"; // x为字符串
数据类型分为两类:简单数据类型(Number、String、Boolean、Underined、Null)、复杂数据类型(Object) ;
数字的最大值Number.MAX_VALUE;
数字的最小值Number.MIN_VALUE;
无穷大:Infinity
无穷小:-Infinity
非数字:NaN(Not a number)
用来判断一个变量是否为非数字: isNaN(X) ,输出为布尔值, 如:
var age = 17;
var isOrNot = isNaN(age);
console.log(isOrNot); // true
字符串型是引号中的任意文本,这个引号可以是双引号,也可以是单引号,推荐使用单引号;
js可以用单引号嵌套双引号,或者用双引号嵌套单引号(外双内单,外单内双)
字符串转义符: 转义符都是\开头的,常用的转义符及其说明如下:
转义符 | 解释说明 |
\n | 换行符,n是newline意思 |
\\ | 斜杠\ |
\' | 单引号 ' |
\" | 双引号 " |
\t | tab缩进 |
\b | 空格,b是blank的意思 |
字符串长度: 通过字符串的length属性可获取整个字符串的长度 string.length
字符串拼接: 一个字符串和任意类型拼接,都会变成一个新的字符串,字符串拼接用+
布尔类型有两个值,true和false,布尔值和数字型相加时,true的值为1,false的值为0;
一个声明后没有被赋值的变量,就会是undefined,undefined类型的变量与数字或布尔值拼接后,都会变成NaN;
一个声明变量给null值,里面存的值为空,Null类型的变量与数字、布尔值结合,当做0处理; 注意:Null的类型是object
通常有三种方式的转换:转换为字符串类型;转换为数字型;转换为布尔型;
转换为字符串:
方式 | 说明 | 案例 |
toString() | 转成字符串 | var num=1; alert(num.toString()); |
String() 强制转换 | 转成字符串 | var num=1; alert(String(num)) ; |
加号拼接字符串 | 和字符串拼接的结果都是字符串 | 要转换的 + ""(这种用的频率最高) |
转换为数字型:
方式 | 说明 | 案例 |
parseInt(String) | 将string类型转成整数数值型 | parseInt("78") |
parseFloat(string) | 将string类型转成浮点数值型 | parseFloat("78.99") |
Number()强制转换函数 | 将string类型转成数值型 | Number('12') |
- * / 隐式转换 | 利用算术运算隐式转换成数值型 | '12' - 0 |
注意:
parseInt取整,和四舍五入没关系,如:
parseInt('4.98'); // 结果为4
parseInt和parseFloat还可以从数字开头的字符中,取出数字,如:
parseInt(128rem); // 结果为128
但是不是数字开头的字符串则不行,如:
parseInt('this128rem'); // 结果为NaN
转换为布尔型
方式 | 说明 | 案例 |
Boolean() | 将其它类型转成布尔值 | Boolean("true") |
注意:代表空、否定的值会被转换为false,如'0'、''、NaN、null、undefined;其余值会被转换为true;
有如下几种方式:算数运算符、递增和递减运算符、比较运算符、逻辑运算符、赋值运算符;
运算符优先级:
优先级 | 运算符 | 顺序 |
1 | 小括号 | () |
2 | 一元运算符 | ++ -- ! |
3 | 算数运算符 | 先* / % 后+ - |
4 | 关系运算符 | < >= < <= |
5 | 相等运算符 | == != === !== |
6 | 逻辑运算符 | 先&& 后|| |
7 | 赋值运算符 | = |
8 | 逗号运算符 | , |
流程结构分为顺序结构、 分支结构与循环结构
顺序结构:无特定语法,按代码先后顺序执行;
分支结构:根据不同的条件,执行不同的路径代码(执行代码多选一的过程),从而得到不同的结果,典型的有if语句和switch语句;
通常在针对变量设置一系列的特定值的选项时,选择switch,switch中表达式的值与下面case中的value匹配,语法如下:
switch(表达式) {
case value1:
// 执行语句1
break;
case value2:
// 执行语句2
break;
case value3:
// 执行语句3
break;
default;
// 执行语句(不等于任何一个value时执行的代码)
}
注意:
如果case中执行语句后面,没有加break,则就会执行下一个case中的语句,直到遇到break执行才会停下来;
三元表达式
表达式 (expr1) ? (expr2) : (expr3)
指表达式expr1为真的时候,执行表达式expr2,反之则执行表达式expr3
在JS中,主要有三种类型的循环语句:for 循环、while循环、do...while循环;
continue关键字用于立即跳出本次循环,继续下一次循环;
break关键字用于跳出当前循环,该循环结束,不再继续循环;
JS中创建数组有两种方式:
利用new创建数组
var 数组名 = new Array();
示例:
var array = new Array(); // 创建一个新的空数组
注意:Array(),A要大写;
利用数组字面量创建数组
var 数组名 = []; // 使用数组字面量方式创建空的数组
var 数组名 = ['小白','小黑','大黄']; // 使用数组字面量方式创建带初始值的数组
声明数组并赋值称为数组的初始化,这种字面量方式使用最多。
数组元素的类型
数组中可存放任意类型的数据,如字符串,数字,布尔值等,如:
var arryexam = ['123', 0, 12.4, true];
获取数组元素
数组的索引(下标)是指用来访问数组元素的序号(数组小标从0开始)。
数组可通过索引来访问、设置、修改对应的数组元素,可通过数组名[索引]的形式来获取数组中的元素。 如:
var arryexam = ['123', 0, 12.4, true];
console.log(arryexam[0]); // 结果是'123'
数组的长度
可通过数组名.length获取数组长度
遍历数组
遍历即是把数组中的每个元素从头到尾都访问一次
数组中新增元素
var arr = ['123', true, 123];
arr.length = 7;
console.log(arr[6]); // 输出结果是undefined
因为索引号是3/4/5/6的空间没有给值,即声明变量未给值,所以默认值是undefined。
var arr = ['123', true, 123];
arr[3] = '234';
console.log(arr) // ['123', true, 123, '234']
注意:不能直接给数组名赋值,否则会覆盖掉以前的数据;
冒泡排序
冒泡排序是一种简单的排序算法,它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行,直到没有再需要交换,也就是说该数列已经排序完成,这个算法的名称由来是由于越小的元素会经由交换慢慢“浮到”数列的顶端。
两个for循环即可解决排序问题:外层for循环解决需要的趟数(趟数是数组长度-1),内层for循环用来解决每一趟交换的次数(次数是从0开始的,所以最终为arr.length-i-1)
Q:冒泡排序每趟都能保证最后一个是大的么?如第一趟排完是最后一个最大,第二趟排完是倒数第二个最大
函数的使用
函数在使用时分为两步:声明函数和调用函数
声明函数有两种方式,一种方式是利用函数关键字自定义函数,也称为命名函数,另外一种方式是通过函数表达式,亦即匿名函数;
调用函数关键字自定义函数(命名函数)
function 函数名() {
// 函数体
}
示例:
function getSum() {
var sum = 0;
for (i = 0;i < 10; i++) {
sum += i;
}
}
函数表达式定义函数(匿名函数)
var 变量名 = function(aru) {
//函数体
}
变量名("奥利给~")
var 变量名 = function(aru) {
console.log('好好学习~')
console.log('天天向上~')
console.log(aru)
}
fun("奥利给~")
函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数~
function getSum() {
var sum = 0;
for (i = 0;i < 10; i++) {
sum += i;
}
}
getSum();
通过函数直接使用函数名()即可; // 通过调用函数名来执行函数体代码
注意:声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码;
是指一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口;
在声明函数时,可在函数名称后面的小括号中添加一些参数,这些参数被称为形参,在调用该函数时,传递的参数叫实参;
如果实参的个数和形参的个数一致,则正常输出结果;
如果实参的个数多于形参的个数,会只取到形参的个数;
如果实参的个数小于形参的个数,则多余的形参定义为undefined,最终的结果就是NaN(undefined做任何操作,结果都为NaN)
形参可看做是不用声明的变量 所以未传实参的变量没有接收值,结果就是undefined
若希望函数将值返回给调用者,此时需要通过return语句就可实现;
return后面的代码不会被执行;并且return只能返回一个值;如果是return多个值,则最终返回的结果依然是最后一个值,如:
return num1, num2; // 结果返回的依然是num2
若想返回多个输出结果,可以将多个结果组成数组再return;如:
return [num1 + num2, num1 - num2, num1* num2];
函数的返回值有三种类型:
break: 结束当前的循环体(如for/while)
continue: 跳出本次循环,继续执行下次循环(如for、while)
return: 不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前的函数体内的代码
当不确定有多少个参数传递的时候,可用arguments来获取。
在JS中,arguments实际上是当前函数的一个内置对象,所有函数都内置了一个 arguments对象,arguments对象中存储了传递的所有参数。(使用arguments就可不用传参数了,适用于不知道形参有几个的情况~)
arguments其实是一个伪数组,并不是真正意义上的数组,但是具有数组的length属性;按照索引的方式进行存储;没有真正数组的一些方法:pop() push()等
作用域即代码名字(变量)在某个范围内起作用和效果,为提高程序的可靠性,更重要的是减少命名冲突; es6之前,作用域分为全局作用域和局部作用域,相应的有全局变量和局部变量;es6新增了块级作用域
全局变量
在全局作用域下的变量,在全局下都可以使用;
注意:若在函数内部,没有声明直接赋值的变量也属于全局变量!!
局部变量
在函数内部的变量即为局部变量;
函数的形参实际上就是局部变量;
从执行效率来看局部和全局变量
全局变量只有浏览器关闭的时候才会销毁,比较占内存资源;
局部变量在所在代码块被执行时被初始化,当代码块运行结束后,就会被销毁,即更节省内存空间;