JavaScript
简介
JavaScript是一门动态弱类型的解释型编程语言。是可插入 HTML 页面的编程代码,插入 HTML 页面后,可由所有的现代浏览器执行。从而增强页面动态效果,实现页面与用户之间的实时动态的交互。
一个完整的JavaScript的实现是由三部分组成:ECMAScript、DOM、BOM
ECMAScript由ECMA-262定义,提供核心语言功能。简单地说,ECMAScript 描述了JavaScript语言本身的相关内容(ECMA是欧洲计算机制造商协会)
DOM(Document Object Model)文档对象模型,提供访问和操作网页内容的方法和接口
BOM(Browser Object Model)浏览器对象模型,提供与浏览器交互的方法和接口
JavaScript引入方式
引入外部的js文件
<script src="javascript.js"></script>
<Script>标签内写代码,存放在HTML的<head>或<body>中
<script> //这里写Js代码内容</script>
HTML的head中VSHTML的body代码块底部(推荐)
为什么要放在<body>代码块底部?
HTML代码从上到下执行,先加载CSS,避免html出现无样式状态;
将JavaScript代码块放在<body>最后,可以让网页尽快的呈现给用户,减少浏览者的等待时间,避免因为JS代码块阻塞网页的呈现。
JavaScript语言规范:注释,结束符
// 单行注释/*多行注释*/; 结束符,JavaScript中的语句要以分号为结束符
变量
JavaScript的变量名可以使用_,数字,字母,$组成,不能以数字开头。
声明变量使用var变量名; 的格式来进行声明
var name = "Hanpi";var age = 18;
变量名是区分大小写的。
推荐使用驼峰式命名规则。
关键字和保留字不能用做变量名。
注意:局部变量必须以 var 开头声明,如果不写 var 则为全局变量
<script> // 全局变量 name = 'hanpi'; function func(){ // 局部变量 var age = 18; // 全局变量 gender = "man" }</script>// 需要注意变量提升,就是把变量位置放到函数体的最上方
数据类型
特殊值:
null 表示值为空,一般都是指定或清空一个变量时才会使用,如 name=null;
undefined 表示当声明一个变量但未初始化时(没有给值),该变量的默认值是undefined。函数无明确的返回值时,返回的也是undefined。
null表示变量的值是空(null可以手动清空一个变量的值,使得该变量变为object类型,值为null),undefined则表示只声明了变量,但还没有赋值。
对象(Object)
JavaScript 中的所有事物都是对象:数值、字符串、数组、函数...此外,JavaScript 允许自定义对象。
JavaScript 提供多个内建对象,比如 String、Date、Array 等等。
对象只是带有属性和方法的特殊数据类型。
1.数值(Number)
JavaScript中不区分整数和浮点数,所有数字均用数值表示。即Number数值类型
转换:
parseInt(..) 将某值转换成整数,不成功则NaN
parseFloat(..) 将某值转换成浮点数,不成功则NaN
特殊值:
NaN,非数字。可以使用 isNaN(num) 来判断。
Infinity,无穷大。可以使用 isFinite(num) 来判断。
var a = 11;var b = 11.11;typeof a; //查看类型typeof b;parseInt("111") //字符串转数值parseFloat("11.11") parseInt(11.11) //浮点数转数值只保留整数部分parseInt("ada111") //转换不成功NaNparseInt("111ada") //只要是数字开头的字符串也可以转换
2.字符串(String)
var a = "Hello"var b = "world;var c = a b; console.log(c); // 得到Helloworld
内置方法:
String.length 字符串的长度String.trim() 移除空白String.trimLeft() 移除左侧空白String.trimRight() 移除右侧空白String.concat(value, ...) 拼接String.slice(start, end) 切片String.split( ) 分割String.search( ) 从头开始匹配,返回匹配成功的第一个位置(g无效)String.match( ) 全局搜索,如果正则中有g表示找到全部,否则只找到第一个String.replace( ) 替换,正则中有规则替换所有,否则只替换第一个匹配项;$数字:匹配的第n个组内容;$&:当前匹配的内容;$:位于匹配子串左侧的文本;$:位于匹配子串右侧的文本$$:直接量$符号String.charAt( ) 返回字符串中的第n个字符String.charCodeAt( ) 返回字符串中的第n个字符的代码String.fromCharCode( ) 从字符编码创建—个字符串String.indexOf( ) 查找子字符串位置String.lastIndexOf( ) 查找子字符串位置String.localeCompare( ) 用本地特定的顺序来比较两个字符串String.substr( ) 抽取一个子串String.substring( ) 返回字符串的一个子串String.toLocaleLowerCase( ) 把字符串转换小写(针对地区,在不知道程序在哪个语言环境中运行时用)String.toLocaleUpperCase( ) 将字符串转换成大写(针对地区)String.toLowerCase( ) 小写String.toUpperCase( ) 大写String.toString( ) 返回原始字符串值String.toString() 返回原始字符串值String.valueOf( ) 返回原始字符串值
3.布尔值(Boolean)
ture 真
false 假
任何数据类型都可以转换为boolean类型
布尔值是fales的有: 空字符串、0、null、undefined、NaN
4. 数组对象(Array)
数组对象的作用是:使用单独的变量名来存储一系列的值。
var Array = [11, 22.33, "aaa"] //定义数组undefinedArray // 查看数组(3) [11, 22.33, "aaa"]var arr =[11,33,55,777,33,10]; //定义数组undefinedarr.sort(function (v1,v2){return v1-v2}); // 排序(6) [10, 11, 33, 33, 55, 777]
常用函数:
Array.length 数组的大小(元素数量)Array.push( ) 尾部添加元素Array.pop( ) 删除并返回数组的最后一个元素Array.unshift( ) 在数组头部插入一个元素Array.shift( ) 在数组头部移除一个元素Array.slice( ) 切片Array.reverse( ) 反转Array.join( ) 将数组元素连接起来以构建一个字符串Array.concat( ) 拼接Array.sort( ) 排序Array.forEach() 将数组的每个元素传递给回调函数Array.splice() 删除元素,并向数组添加新元素。Array.map() 返回一个数组元素调用函数处理后的值的新数组Array.toLocaleString( ) 把数组转换成局部字符串Array.toString( ) 将数组转换成一个字符串
forEach()
语法:
forEach(function(currentValue, index, arr), thisValue)
参数:
参数 | 描述 |
---|---|
function(currentValue, index, arr) | 必需。 数组中每个元素需要调用的函数。 函数参数:参数描述currentValue必需。当前元素index可选。当前元素的索引值。arr可选。当前元素所属的数组对象。 |
thisValue | 可选。传递给函数的值一般用 "this" 值。 如果这个参数为空, "undefined" 会传递给 "this" 值 |
splice()
语法:
splice(index,howmany,item1,.....,itemX)
参数:
参数 | 描述 |
---|---|
index | 必需。规定从何处添加/删除元素。 该参数是开始插入和(或)删除的数组元素的下标,必须是数字。 |
howmany | 必需。规定应该删除多少元素。必须是数字,但可以是 "0"。 如果未规定此参数,则删除从 index 开始到原数组结尾的所有元素。 |
item1, ..., itemX | 可选。要添加到数组的新元素 |
map()
语法:
map(function(currentValue,index,arr), thisValue)
参数:
参数 | 描述 |
---|---|
function(currentValue, index,arr) | 必须。函数,数组中的每个元素都会执行这个函数 函数参数: 参数描述currentValue必须。当前元素的值index可选。当期元素的索引值arr可选。当期元素属于的数组对象 |
thisValue | 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。 如果省略了 thisValue ,"this" 的值为 "undefined" |
5.Date日期对象
//方法1:不指定参数var d1 = new Date();console.log(d1.toLocaleString());//方法2:参数为日期字符串var d2 = new Date("2018/01/27 11:12:13");console.log(d2.toLocaleString());var d3 = new Date("01/27/18 11:12:13"); // 月/日/年 时分秒console.log(d3.toLocaleString());//方法3:参数为毫秒数var d4 = new Date(7000);console.log(d4.toLocaleString());console.log(d4.toUTCString());//方法4:参数为:年,月,日,时,分,秒,毫秒var d5 = new Date(2018,1,27,11,12,13,700);console.log(d5.toLocaleString()); //毫秒并不直接显示
常用方法:
方法 | 含义 |
---|---|
getDate() | 根据本地时间返回指定日期对象的月份中的第几天(1-31)。 |
getMonth() | 根据本地时间返回指定日期对象的月份(0-11) |
getFullYear() | 根据本地时间返回指定日期对象的年份(四位数年份时返回四位数字) |
getDay() | 根据本地时间返回指定日期对象的星期中的第几天(0-6) |
getHours() | 根据本地时间返回指定日期对象的小时(0-23) |
getMinutes() | 根据本地时间返回指定日期对象的分钟(0-59) |
getSeconds() | 根据本地时间返回指定日期对象的秒数(0-59) |
getMilliseconds() | 根据本地时间返回指定日期对象的获取毫秒 |
getTime() | 返回累计毫秒数(从1970/1/1午夜) |
练习:
编写代码,将当前日期按“2017-12-27 11:11 星期三”格式输出。
const WEEKMAP = { 0:"星期天", 1:"星期一", 2:"星期二", 3:"星期三", 4:"星期四", 5:"星期五", 6:"星期六"}; //定义一个数字与星期的对应关系对象function showTime() { var d1 = new Date(); var year = d1.getFullYear(); var month = d1.getMonth() 1; //注意月份是从0~11 var day = d1.getDate(); var hour = d1.getHours(); var minute = d1.getMinutes() < 10?"0" d1.getMinutes():d1.getMinutes(); //三元运算 var week = WEEKMAP[d1.getDay()]; //星期是从0~6 var strTime = ` ${year}-${month}-${day} ${hour}:${minute} ${week} `; console.log(strTime)};showTime();参考示例
6. Math对象
Math对象是一个静态对象,而不是构造函数。实际上,Math只是一个由Javascript设置的对象命名空间,用于存储数学函数。
作用是执行普通的算数任务。
方法 | 含义 |
---|---|
Math.floor() | 向下取整,如5.1取整为5 |
Math.ceil() | 向上取整,如5.1取整为6 |
Math.max(a,b) | 求a和b中的最大值 |
Math.min(a,b) | 求a和b中的最小值 |
Math.random() | 随机数,默认0-1之间的随机数,若想求min~max之间的数,公式为:min Math.random()*(max-min) |
7. 自定义对象
JavaScript的对象(Object)本质上是键值对的集合(Hash结构),但是只能用字符串作为键。
var a = {"name": "Alex", "age": 18};console.log(a.name);console.log(a["age"]);
遍历对象中的内容:
var a = {"name": "Alex", "age": 18};for (var i in a){ console.log(i, a[i]);}
创建对象:
var person=new Object(); // 创建一个person对象person.name="Alex"; // person对象的name属性person.age=18; // person对象的age属性
注意:
ES6中提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当做键。
也就是说,Object结构提供了“字符串--值”的对应,Map结构提供了“值--值”的对应,是一种更完善的Hash结构实现。
8. JSON对象
var str1 = '{"name": "Alex", "age": 18}';var obj1 = {"name": "Alex", "age": 18};// JSON字符串转换成对象var obj = JSON.parse(str1); // 对象转换成JSON字符串var str = JSON.stringify(obj1);
9. RegExp对象
// 定义正则表达式两种方式var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9]{5,11}");var reg2 = /^[a-zA-Z][a-zA-Z0-9]{5,9}$/;// 正则校验数据reg1.test('jason666')reg2.test('jason666')/*第一个注意事项,正则表达式中不能有空格*/ // 全局匹配var s1 = 'egondsb dsb dsb';s1.match(/s/)s1.match(/s/g)var reg2 = /^[a-zA-Z][a-zA-Z0-9]{5,9}$/greg2.test('egondsb');reg2.test('egondsb');reg2.lastIndex;/*第二个注意事项,全局匹配时有一个lastIndex属性*/// 校验时不传参数var reg2 = /^[a-zA-Z][a-zA-Z0-9]{5,9}$/reg2.test();reg2.test(undefined);var reg3 = /undefined/;reg3.test();RegExp
运算符
1.算术运算符
运算符 | 描述 |
---|---|
加法 | |
- | 减法 |
* | 乘法 |
** | 幂 |
/ | 除法 |
% | 取余数 |
递增 | |
-- | 递减 |
var x = 10;var res1 = x ;var res2 = x;res1 = 10res2 = 12这里由于的x 和 x在出现赋值运算式,x 会先赋值再进行自增1运算,而 x会先进行自增运算再赋值!
2.比较运算符
运算符 | 描述 |
---|---|
== | 等于 |
=== | 值相等并且类型相等 |
!= | 不相等 |
!== | 值不相等或类型不相等 |
> | 大于 |
< | 小于 |
>= | 大于或等于 |
<= | 小于或等于 |
1 == '1'; 弱等于:内部自动转换成相同的数据类型比较了ture1 === '1'; 强等于:内部不做类型转换false!1 === '1';false!(1 === '1');ture
3.逻辑运算符
运算符 | 描述 |
---|---|
! 非 | 返回一个布尔值 (两个!!表示Boolean()转型函数 |
&& 与 | 两个操作都为true时返回true,否则返回false(返回值不一定是布尔值),可以多个连用(..&&..&&..) |
|| 或 | 两个操作都是false时返回false,否则返回true(返回值不一定是布尔值),可以多个连用(..||..||..) |
10 > 3 && 3 > 2;ture10 < 3 || 3 > 2;ture10 < 3 || !3 > 2;false
流程控制
1、条件语句
JavaScript中支持两个条件语句,分别是:if 和 switch。
if 语句:
//if->else语句:var age = 30;if(age > 18){ console.log('too old');}else { console.log('too young');}//if->else if->else语句:var age=18;if(age > 18){ console.log('你个老baby');}else if(age == 18){ console.log('你个嘚嘚');}else { console.log('你个小毛头');}
Switch 语句:
//switch语句,name等于geng是执行第一个case,等于第二个执行第二个case,其它执行default.var name = "geng"switch(name){ case 'geng': age = 18; break; case 'yang': age = 21; break; default: age = 0;}
2、循环语句
JavaScript中支持四种循环语句,分别是:for、for in、while、do-while
for 循环:
var names = ["geng", "yang"];for(var i=0;i<names.length;i ){ console.log(i); //索引 console.log(names[i]);}
for in 循环:
var names = ["geng", "yang"];for(var index in names){ console.log(index); console.log(names[index]);}
while 循环:
while(条件){ // break; // continue;}
do-while 循环:
//循环的代码至少执行一次,结果为1var num = 0;do { num ;}while (num>10);
三元运算
var res = 10 > 3 ?"OK":"NO";res"OK"
函数
JavaScript 函数是通过 function 关键词定义的。
可以使用函数声明或函数表达式。
函数定义:
// 普通函数定义function f1() { console.log("Hello world!");};f1();// 有参数函数定义function f2(a, b) { console.log(arguments); // 内置的arguments对象 console.log(arguments.length); console.log(arguments[0],arguments[1]); console.log(a, b);};f2(10,20);// 带返回值的函数function sum(a, b){ return a b;}sum(1, 2); // 调用函数// 匿名函数var sum = function(a, b){ return a b;}sum(1, 2);// 立即执行函数,书写立即执行的函数,首先先写两个括号()()这样防止书写混乱(function(a, b){ return a b;})(1, 2);
函数中的arguments参数:
arguments 指的是传递到函数或由函数接收到的真实值
函数传参的个数可以小于实际需传参的个数,没传参的默认为undefined
参数传多默认不起作用
function f1(a,b) { var res=a b; console.log(res); console.log(arguments); // a,b会被封装到arguments 里面 return res;}f1(1,2);Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]//arguments 可接收所有参数,返回一个数组,后面跟的是描述信息function f1(a,b) { console.log(arguments); // 打印数组 console.log(arguments[0]); // 1 打印对应的第一参数值 console.log(arguments[1]); // 2 打印的第二个参数值 console.log(arguments.length); // 2 总共长度为2}f1(1,2);
函数的全局变量和局部变量
局部变量:
在JavaScript函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它(该变量的作用域是函数内部)。只要函数运行完毕,本地变量就会被删除。
全局变量:
在函数外声明的变量是全局变量,网页上的所有脚本和函数都能访问它。
变量生存周期:
JavaScript变量的生命期从它们被声明的时间开始。
局部变量会在函数运行以后被删除。
全局变量会在页面关闭后被删除。
作用域
首先在函数内部查找变量,找不到则到外层函数查找,逐步找到最外层。与python作用域关系查找一模一样!
几个例子:
1.
var city = "BeiJing";function f() { var city = "ShangHai"; function inner(){ var city = "ShenZhen"; console.log(city); } inner();}f(); //输出结果是?
2.
var city = "BeiJing";function Bar() { console.log(city);}function f() { var city = "ShangHai"; return Bar;}var ret = f();ret(); // 打印结果是?
3.闭包
var city = "BeiJing";function f(){ var city = "ShangHai"; function inner(){ console.log(city); } return inner;}var ret = f();ret();
词法分析(尝试理解)
JavaScript中在调用函数的那一瞬间,会先进行词法分析。
词法分析的过程:
当函数调用的前一瞬间,会先形成一个激活对象:Avtive Object(AO),并会分析以下3个方面:
1:函数参数,如果有,则将此参数赋值给AO,且值为undefined。如果没有,则不做任何操作。 2:函数局部变量,如果AO上有同名的值,则不做任何操作。如果没有,则将此变量赋值给AO,并且值为undefined。 3:函数声明,如果AO上有,则会将AO上的对象覆盖。如果没有,则不做任何操作。
函数内部无论是使用参数还是使用局部变量都到AO上找。
看两个例子:
var age = 18;function foo(){ console.log(age); var age = 22; console.log(age);}foo(); // 问:执行foo()之后的结果是?
第二题:
var age = 18;function foo(){ console.log(age); var age = 22; console.log(age); function age(){ console.log("呵呵"); } console.log(age);}foo(); // 执行后的结果是?
词法分析过程:1、分析参数,有一个参数,形成一个 AO.age=undefine;2、分析变量声明,有一个 var age, 发现 AO 上面已经有一个 AO.age,因此不做任何处理3、分析函数声明,有一个 function age(){...} 声明, 则把原有的 age 覆盖成 AO.age=function(){...};最终,AO上的属性只有一个age,并且值为一个函数声明执行过程:注意:执行过程中所有的值都是从AO对象上去寻找1、执行第一个 console.log(age) 时,此时的 AO.age 是一个函数,所以第一个输出的一个函数2、这句 var age=22; 是对 AO.age 的属性赋值, 此时AO.age=22 ,所以在第二个输出的是 23、同理第三个输出的还是22, 因为中间再没有改变age值的语句了答案解析