[JavaScript]

[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>

2、Script标签内写代码、存放爱HTML的head或body中

<script>
  //这里写Js代码内容
</script> 
  • HTML的head中VSHTML的body代码块底部(推荐)
  1. 为什么要放在代码块底部?
  • HTML代码从上到下执行,先加载CSS,避免html出现无样式状态;
  • 将JavaScript代码块放在最后,可以让网页尽快的呈现给用户,减少浏览者的等待时间,避免因为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") //只要是数字开头的字符串也可以转换

img

2、字符串(String)

var a = "Hello"
var b = "world;
var c = a + b; 
console.log(c);  // 得到Helloworld

img

内置方法:

img 字符串内置方法

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]

img

常用函数:

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" 值

img

splice()

语法:

splice(index,howmany,item1,.....,itemX)

参数:

参数 描述
index 必需。规定从何处添加/删除元素。 该参数是开始插入和(或)删除的数组元素的下标,必须是数字。
howmany 必需。规定应该删除多少元素。必须是数字,但可以是 "0"。 如果未规定此参数,则删除从 index 开始到原数组结尾的所有元素。
item1, ..., itemX 可选。要添加到数组的新元素

img

map()

语法:

map(function(currentValue,index,arr), thisValue)

参数:

参数 描述
function(currentValue, index,arr) 必须。函数,数组中的每个元素都会执行这个函数 函数参数: 参数描述currentValue必须。当前元素的值index可选。当期元素的索引值arr可选。当期元素属于的数组对象
thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。 如果省略了 thisValue ,"this" 的值为 "undefined"

img

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 星期三”格式输出。

img 参考示例

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';  弱等于:内部自动转换成相同的数据类型比较了
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 循环://循环的代码至少执行一次,结果为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作用域关系查找一模一样!

几个例子:

var city = "BeiJing";function f() {  var city = "ShangHai";  function inner(){    var city = "ShenZhen";    console.log(city);  }  inner();}f();  //输出结果是?
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()之后的结果是?

img

第二题:

var age = 18;
function foo(){
  console.log(age);
  var age = 22;
  console.log(age);
  function age(){
    console.log("呵呵");
  }
  console.log(age);
}
foo();  // 执行后的结果是?

img

img

词法分析过程:
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-05-15 14:41  刘较瘦丫  阅读(49)  评论(0)    收藏  举报