JavaScript

简介

  JavaScript是一门动态弱类型的解释型编程语言。是可插入 HTML 页面的编程代码,插入 HTML 页面后,可由所有的现代浏览器执行。从而增强页面动态效果,实现页面与用户之间的实时动态的交互。

  一个完整的JavaScript的实现是由三部分组成:ECMAScript、DOM、BOM

  • ECMAScript由ECMA-262定义,提供核心语言功能。简单地说,ECMAScript 描述了JavaScript语言本身的相关内容(ECMA是欧洲计算机制造商协会)

  • DOM(Document Object Model)文档对象模型,提供访问和操作网页内容的方法和接口

  • BOM(Browser Object Model)浏览器对象模型,提供与浏览器交互的方法和接口

 

JavaScript引入方式

  1. 引入外部的js文件

<script src="javascript.js"></script>

 

  1. <Script>标签内写代码,存放在HTML的<head>或<body>中

<script>
  //这里写Js代码内容
</script> 

 

  • HTML的head中VSHTML的body代码块底部(推荐)

  1. 为什么要放在<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 等等。

对象只是带有属性和方法的特殊数据类型。

img

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") //转换不成功NaN
parseInt("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"] //定义数组
undefined
Array // 查看数组
(3) [11, 22.33, "aaa"]
​
var arr =[11,33,55,777,33,10]; //定义数组
undefined
arr.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}$/g
reg2.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 = 10
res2 = 12
这里由于的x++和++x在出现赋值运算式,x++会先赋值再进行自增1运算,而++x会先进行自增运算再赋值!

2.比较运算符

运算符描述
== 等于
=== 值相等并且类型相等
!= 不相等
!== 值不相等或类型不相等
> 大于
< 小于
>= 大于或等于
<= 小于或等于
1 == '1';  弱等于:内部自动转换成相同的数据类型比较了
ture
​
1 === '1'; 强等于:内部不做类型转换
false
!1 === '1';
false
!(1 === '1');
ture
 

 

3.逻辑运算符

运算符描述
! 非 返回一个布尔值 (两个!!表示Boolean()转型函数
&& 与 两个操作都为true时返回true,否则返回false(返回值不一定是布尔值),可以多个连用(..&&..&&..)
|| 两个操作都是false时返回false,否则返回true(返回值不一定是布尔值),可以多个连用(..||..||..)
10 > 3 && 3 > 2;
ture
10 < 3 || 3 > 2;
ture
10 < 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 循环:

//循环的代码至少执行一次,结果为1
var 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 ,所以在第二个输出的是 2
3、同理第三个输出的还是22, 因为中间再没有改变age值的语句了
​
答案解析
posted @ 2021-03-11 13:30  山风有耳  阅读(84)  评论(0编辑  收藏  举报