全部JavaScript内容整理,全文除前面内容因知识较琐碎或为了更好的表达而用了部分图片外,共计约6万字,全手打。全部整理在一起而不是分开来写,主要是方便以后有疑问直接Ctrl + F搜索文档,即可查询。
JS主要分为3部分,即 ECMAScript , DOM,BOM。移动端暂时没写进来。
因时间仓促,每天凌晨挤时间整理,难免有遗漏,以后发现后会回来补。
话不多说,干货奉上~
JavaScript
计算机基础(了解)
数据存储单位
bit byte kb Gb Tb
如图:
java和javascript的关系: 两者毫无关系。类似于雷锋和雷峰塔的关系。 script是脚本的意思。javascript 是脚本语言,会逐行解释执行。简称JS。
html / css / js三者的关系
三者的简单介绍
html / css 标记语言 ---- 描述类语言 html 决定网页结构和内容(决定看到什么)。相当于人的身体。比如这样:
css决定网页呈现给用户的模样(决定好不好看)。相当于给人穿衣服、化妆等。比如这样:
JS脚本语言---- 编程类语言
实现业务逻辑和页面控制(决定功能)。相当于人做出的各种动作。比如这样:
JS的组成
JS包括三部分: 1,ECMAScript ,即欧洲计算机制造商协会通过的一种标准化的脚本程序设计语言。在这之前,脚本语言比较混乱。 2,DOM,即document object model 页面文档对象模型。它的主题是document。 3,BOM,即brower object model 浏览器对象模型。其实更应该叫做 WOM,即 window object model ,因为它的作用对象就是window。
JS的三种书写位置(和CSS非常相似)
1,**行内式**。即 直接写在标签里。比如:
特点:
①可以将单行或者少量JS代码写在HTML标签的事件属性中(以on开头的属性),如:onclick。
②注意单双引号的使用:在THML中推荐使用双引号,在JS中推荐使用单引号。
③可读性差,在HTML中编写JS大量代码时,不方便阅读;
④引号易错,引号多层嵌套匹配时,非常容易弄混淆。
⑤在特殊情况下使用。
2,内嵌式。写在被head标签包含。比如:
<head> <script> alert('hello world'); </script> </head>
特点:①可以将多行JS写到
<body> <div> </div> ... <script src="j;></script> </body>
①利于HTML页面代码结构化,把大段JS代码独立到HTML页面之外,既美观,又方便文件级别的复用。②引用外部JS文件的
JS的注释方法(这点和java一样的)
1,单行注释: //内容 2,多行注释:
/* 内容
内容
内容*/
JS输入输出语句:
1,在F12里输出: console('内容'); 2,在页面弹窗里输出: alert('内容'); 3,在页面弹窗里输入:prompt('内容');
JS变量
什么是变量
白话:变量就是一个装东西的盒子。 通俗:变量是用于存放数据的容器。完美通过**变量名**获取数据,甚至可以修改数据。 比如以下三种变量:
变量在内存中的存储
本质:变量是程序在内存中申请的一块用来存放数据的空间。比如:
类似于酒店的房间,一个房间就可以看作一个变量。
变量的使用
变量在使用时分为两步: 1,**声明变量**。
//声明一个名称为age的变量。 var age;
①var是JS的一个关键字。用来声明变量(variable变量的意思)。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员管。
②age是程序员定义的变量名。我们要通过变量名来访问内存中分配的空间。
2,给变量赋值。
age = 10;//给age这个变量赋值为10.
① = 用来把右边的值 赋给左边的变量空间中。此处代表赋值的意思。
②变量值是程序员保存到变量空间里的值。
3,变量的初始化。
var age = 18; //声明变量同时赋值为18.
声明一个变量并赋值,我们称之为变量的初始化。
变量的语法扩展
1,更新变量 一个变量被重新赋值后,它原有的值就会被覆盖。变量值将以最后一次赋的值为准。
var age = 18; age = 19;//最后的结果就是19.因为18被新赋值的19给覆盖了。
2,同时声明多个变量
同时声明多个变量时,只需要写一个var,多个变量名之间使用英文逗号隔开。比如:
var age = 10, name = 'zs', sex = 2;
3,声明变量的特殊情况。
①只声明,不赋值。比如:
var age; con(age);
输出结果就是 undefined。
②不声明,只赋值。
age = 10; con(age);
输出结果是 10.
③不声明,不赋值
con(age);//没声明,也没赋值
输出结果时直接报错。
变量的命名规范
提示:也不要用name作为变量名。
数据类型
为啥需要数据类型
在计算机中,不同的数据所需占用的存储空间是不同的,为了便于把数据分成所需内存大小不同的数据,充分利用存储空间。于是定义了不同的数据类型。
变量的数据类型
变量是用来存储值的所在处,它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。JS是一种弱类型或者说是动态语言。这意味着不用提前声明变量的类型,在程序运行过程中,类型会被自动确定。
/*JS的变量数据类型是只有程序在运行过程中, 根据等号右边的值来确定的。*/ 比如: var age = 10; //这个age变量是一个数字型。 var areYouOk = '是的'; //这是一个字符串。 //在代码运行时,变量的数据类型是由JS根据等号右边的变量值的数据类ing来判断的。 //运行完毕后,变量就确定了数据类型。
JS拥有动态类型,同时也意味着相同的变量科用作不同的类型。比如:
var x = 6; //变量x是数字。 var x = 'Bill'; //现在x是字符串了。
简单数据类型(基本数据类型)
JS中的简单数据类型及其说明如下: 数字型 布尔型 字符串型 undefined null 五个类型。
数字型的三个特殊值
Infinity -Infinity NaN
判断一个变量是否为非数字型: isNaN() 。
字符串型String
字符串转义符
字符串长度
变量.length
var strMsg = 'haha'; aler);//输出结果是4
字符串拼接
拼接符: + 字符串 + 任何类型 = 拼接之后的新字符串类型 拼接前会把与字符串相加的任何类型转换成字符串,再拼接成一个新的字符串。
拼接号 + 的口诀: 数值相加,字符相连。还有一种常用情形: 字符串 + 变量 + 字符串比如:
var age = 18; con('我今年' + age + '岁了');//输出结果:我今年18岁了
布尔型 Boolean
布尔类型有两个值: true 真 和 false 假 。 布尔型和数字型相加的时候,true的值是1, false的值是0.
con(ture + 1);//2 con(false + 1); //1
undefined 和 null
获取变量的数据类型
typeof() 可用来获取检测变量的数据类型。
数据类型转换
转换成字符串类型有三种方法: 1,变量.toString() 。 2,String(变量)。 3, ' ' + 变量 。 经常用的方式。
转换为数字型
有4种方法: 1,parseInt(变量)。这是转换为整数数字型。小数不行。 2,parseFloat(变量) 。这是转换为小数的数字型。 3, Number(变量) 。 4,利用运算符号 - * / ,进行隐式转换。 ‘12’ - 0 , ‘123’ - ‘120’ 。
如何判断一个数是整数
有两种方法: 1, 如果一个数是整数,那么parseInt()函数和parseFloat() 函数的返回值是相同的,反之返回不同的值说明是小数,根据这个特点来判断一个数是整数还是小数。 2, 用Number.isInteger(变量)来检验。
Number.isInteger(3) // true Number.isInteger) // false Number.isInteger('') // false Number.isInteger('3') // false Number.isInteger(true) // false Number.isInteger([]) // false
转换为布尔型
方法: Boolean(变量)。
运算符(Operater)
算术运算符
符号: + - * / %
算术运算符优先级问题: 先乘除,后加减,有()就先算()里面的。
浮点数的精度问题
浮点数值的最高精度是17位小数,但在进行计算时其精度远远不如整数。
递增和递减运算符(容易懵,多练习!)
前置递增运算符
++num ; 类似于 num = num + 1; 先自加,后赋值。
后置递增运算符
num++; 类似于 num = num + 1 ; 先赋值,后自加。
总结:前置就是先自加,后置就是后自加。
比较运算符
两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值(true/ false)作为比较运算的结果。 运算符号: > < >= <= == != === !==
注意:‘37’ == 37 true ==会把字符串型的37转化为数字型的37,然后再和37进行比较。
===就不会转换了。
逻辑运算符 && || !
返回值也是布尔值。经常用于多个条件的判断。 && : 一假为假,全真为真。 || : 一真为真,全假为假。 ! : 非真为假, 非假为真。
逻辑运算符的短路运算(逻辑中断)
表达式1 && 表达式2: 如果1为真,则返回表达式2 。如果1为假,返回表达式1 。 就不会再去看表达式2了,更不会去执行。
con(1 && 2);//结果: 2 con(0 && 6);//结果: 0
||的短路运算。
和&&刚好相反。 如果表达式1的结果为真,则返回表达式1,就根本不会再去看表达式2写的什么了,表达式2根本就不会有执行的机会; 如果表达式1为假,那么返回表达式2.
con(1 || 2);//结果: 1 con(0 || 1);//结果: 1
赋值运算符 = += -= *= /= %=
num += 2 相当于 num = num + 2;其他符号类似。
运算符的优先级
如下表:
流程控制:控制代码的执行顺序
分为三种结构: 1,顺序结构。就是按照正常的顺序,由前到后依次执行。 2,分支结构: if ,if else,else 。三元表达式 , switch语句。
if(条件语句) { 执行语句; } else { 执行语句; } ---- if() { } else if { } else if { } ... else { } ----- 三元表达式: 条件表达式 ? 执行语句1 : 执行语句2 ------ switch (表达式) { case 值1: 执行语句1; break; case 值2: 执行语句1; break; ... default: 最后执行语句; } /*就是拿着switch表达式的值和case的值进行匹配, 匹配到哪个就输出哪个,匹配后退出。最后匹配不到,就执行最后语句。 匹配的时候,必须是===全等关系,即值和类型都一样,才可以匹配。 如果当前的case里面没有break,就会继续执行下一个case,不管当前有没有匹配上。 直到遇到break为止,才会退出。*/
if else结构 和 if else if 结构的区别: 如果有一个else if满足条件并执行语句,那么直接退出,并且剩下的所有else if都将不会被访问。
3,循环结构: for , while , do while 。
for(初始化变量; 条件表达式; 操作表达式){ 被循环的语句; } for(var i = 1; i <= 100; i++) { con('hello world'); } 执行顺序:1,先执行var i = 1; 2,再执行判断语句 i <= 100; 3,接着执行 con('hello world'); 4,最后执行 i++ 5,第二轮:这时候 i的值变成2 了, 仍然是先执行var i = 1; 依此类推。 断点判断法,判断执行顺序。 F12 里面 sources 找到需要调试的文件 在程序的某一行设置断点。 ------------------------ while(条件表达式){ 循环体代码; }
while执行思路:
do { 循环体代码-条件表达式为true时 重复执行循环体代码; }while(条件表达式);
do while 执行思路:
循环小结
循环中的continue 关键字
意思是 退出当前条件下的循环,直接跳到下一次的循环继续进行。
例如,小朋友能吃5个包子,当他准备吃第3个包子的时候,发现包子里有虫子,然后把第3个包子扔掉了,继续去吃第4个包子和第5个包子。 所以他一共只吃了4个包子。
循环中的break关键字
意思是 退出从当前条件下的剩余所有循环。到此就终止所有循环了。
例如,小朋友能吃5个包子,当他准备吃第3个包子的时候,发现包子里有虫子,一气之下把第3个包子扔掉了,接着第4个和第5个包子也扔掉了。所以他一共只吃了2个包子。
数组:本质就是变量。可以存更多值的变量!
如图:
创建数组
两种方法: 1,用new创建数组。
var 数组名 = new Array(); var arr = new Array();//创建了一个新的空数组
2,用数组字面量创建数组[ ](更简单)
//1,使用数组字面量方式创建空的数组 var arr = []; //2,使用数组字面量方式创建带初始值的数组 var arr1 = ['1','haha','pink']
数组的索引
//定义数组 var arrStus = [1,2,3]; //获取数组中的第二个元素 con(arrStus[1]); //操作数组的行为,都是通过操作索引号来完成的。
用循环可以遍历数组。
给数组新增元素,给数组扩容
方法1: 修改length长度。
//就是直接让length属性等于另外一个值。
方法2: 修改数组索引新增数组元素。
冒泡排序
#### 把一系列数据从大到小或从小到大排序显示。
两两比较,交换位置。
函数
就是封装的一段可被重复调用执行的代码块。封装就是用{}包起来。有点像电脑主机把里面的零件包起来。
函数的使用:先声明一个函数,再调用函数。
声明函数
//声明函数 function 函数名() { //函数体代码 } //function是声明函数的关键字,必须小写。 /*由于函数一般是为了实现某个功能才定义的, 所以通常我们将函数名 命名为动词,比如getSum*/
调用函数
//调用函数 函数名();//通过调用函数名来执行函数体代码。 //调用的时候千万不要忘记添加() /*口诀: 函数不调用,自己不执行。 即 声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。*/
函数的参数
参数分为形参和实参。
//声明时: function 函数名(形参1,形参2...) { ... } //调用时: 函数名(实参1,实参2...)
形参就是不用声明的变量。
用法举例:
function cook(aru) { con(aru); } cook('番茄炒蛋'); cook('黄瓜炒蛋');
函数的返回值
用return语句。 把返回值返回给函数调用者。由函数调用者决定是否输出。举例:
function getSum(num1, num2) { return num1 + num2; } con(getSum(1, 2));
return最多只能返回一个值。
如果确实需要返回多个值,可以用数组。return[值1, 值2…]。
函数如果有return,则返回return后面的值。
如果没有return,返回的是undefined 。
return的另一个用处: 终止return后面的代码。也就是函数中return后面的代码不会再被执行。
arguments
只有函数才有arguments,函数内置的,默认存在的。 arguments就是一个默认存在的数组。不用创建,可以直接拿来用。
//arguments的使用 function fn() { con(arguments);//里面存储了所有传递过来的实参。 con); con(arguments[2]); //我们可以按照数组的方式遍历arguments for(var i = 0;i < argumen; i++) { con(arguments[i]); } } //调用上面的函数。 fn(1, 2, 3); fn(1,2,3,4,5);
arguments应用举例:
//利用函数求任意个数的最大值 function getMax() { var max = arguments[0]; for(var i = 0; i < argumen; i++) { if(arguments[i] > max) { max = arguments[i]; } } return max; } con(getMax(1,2,3)); con(getMax(11,2,34,444,5,100));
函数可以调用另一个函数
因为每个函数都是独立的代码块,用于完成特殊任务,因此经常会用到函数相互调用的情况。
举例:
function fn1() { con(111); //这里是执行的第**二**步。 输出111. **fn2();** //这里是执行的第**三**步。 调用fn2()函数。 con('fn1'); //第**六**步。fn1()函数还没执行完,继续执行。 输出fn1. } function fn2() { con(222); //这里是执行的第**四**步。 开始执行fn2()函数里的语句。输出222. con('fn2'); //这里是执行的第**五**步。 输出fn2. } fn1(); //执行顺序:上面的fn1()和fn2()函数都还没调用,不执行。这里是第**一**步。 调用fn1()函数。
函数的声明
两种声明方式:
1,利用函数关键字自定义函数(命名函数)
function fn() { ... } fn();//调用函数。 //这种声明方式就是前面讲的构造函数的方式。
2,函数表达式(匿名函数)
var 变量名 = function() { ... } 变量名();//调用函数 注意: 1,函数表达式声明方式跟声明变量差不多, 只不过变量里面存的是一个函数。 2,函数表达式也可以传递参数。比如: var fun = function(aru) { con('我是函数表达式'); } fun('pink');
作用域
分为 全局作用域 和 局部作用域。 //局部作用域也叫函数作用域,因为在函数内部的变量都是局部变量。在函数外面不起作用。
注意:如果在函数内部,没有声明,直接赋值的变量,也属于全局变量。例如:
正常的声明变量 var num1 = 10;这个在函数中声明,就是局部变量。
如果直接写 num2 = 20; 那么num2就是一个全局变量了。(但是这种情况要避免使用。以免混淆)
预解析
js引擎运行js代码分为两步:先预解析,再执行代码。
例如:
con(num);//undefined var num = 10; //相当于执行了以下代码,先预解析,再执行: var num; con(num); num = 10;
fun();//报错 var fun = function() { con(22); } //相当于执行了以下代码 var fun; fun(); fun = function() { con(22); }
案例1:结果是几?
//案例1 var num = 10; fun(); function fun() { con(num); var num = 20; } ------------------ 预解析: var num = 10; function fun() { var num; con(num); num = 20; } fun(); //最后输出是 defined;
//案例2:结果是几? f1(); con(c); con(b); con(a); function f1() { var a=b=c=9; con(a); con(b); con(c); } --------预解析小知识点---------- var a=b=c=9; //相当于 var a = 9; b = 9; c = 9; b和c直接赋值,没有var声明。所以b和c是全局变量。 而a有var声明,所以是函数内的局部变量。 如果改成var a = 9, b = 9, c = 9;那么,a b c都被var声明了,就都是函数内的局部变量。这种声明方式叫集体声明。
对象Object:万物皆对象
对象必须是一个具体的事物。比如明星不是对象,而具体的明星迪丽热巴就是一个对象。
什么是对象
为什么需要对象
保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组。如果保存一个人的完整信息呢?例如,将张三疯的个人信息保存在数组中的方式为:
var arr = ['张三疯', '男', 128, 154];
里面的值分别代表什么呢?数组可以存储值,但是不能完整的把意思表达清楚。而JS中的对象表达结构更清晰,更强大。张三疯的个人信息在对象中的表达结构如下:
创建对象的三种方式
在JS中,现阶段外面可以采用三种方式创建对象: 1,**利用字面量创建对象**
var obj = {};//这样就创建了一个空对象 //像不像数组的字面量创建方式:var arr = []; var obj = { uname: '张三疯', age: 18, sex: '男', sayHi: function() { con('hi~'); } } //对象创建好了,怎么使用呢? //(1)调用对象的属性 对象名.属性名。如: con); //(2)调用方法2: 对象名['属性名'] con(obj['age']); //(3)调用对象的函数sayHi 对象名.方法名() //千万不要忘记小括号 obj.sayHi();
如上,uname这些属性后面需要加逗号,同理,sayHi函数如果后面还有函数,这个函数写完后,仍然需要加逗号,和下一个函数隔开。(是不是很像数组存储值的方式??)
2,利用new Object创建对象
var obj = new Object();//创建了一个空对象 obj.uname = '张三疯'; obj.age = 18; obj.sex = '男'; obj.sayHi = function() { con('hi~'); } //外面是利用等号 = 赋值的方法,添加对象的属性和函数 //每个属性和方法之间用分号结束;
3,利用构造函数创建对象
为什么需要使用构造函数?
前面的两种创建对象方式 依次只能创建一个对象。每次创建一个对象后,对象之间有很多的属性和方法是相同的。只能一直复制。 所以可以利用函数的方法,重复这些相同的代码,这样的函数就叫 构造函数。
构造函数和普通函数不一样的是,它里面封装的是对象,而非普通的可重复代码。
构造函数 就是把对象里面一些相同的属性和方法抽象出来 封装到函数里。
构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。我们可以把对象中的一些公共的属性和函数抽取出来,然后封装到这个函数里面。
//利用构造函数创建对象 //我们想要创建四大天王的对象 相同的属性有:名字 年龄 性别 //相同的方法有: 唱歌 //构造函数的语法格式: function 构造函数名() { this.属性 = 值; this.方法 = function() {} } new 构造函数名(); -----------开始创建对象-------- function Star(uname, age, sex) { = uname; = age; = sex; = function(sang) { con(songs); } } var ldh = new Star('刘德华', 18, 男);//调用函数返回的是一个对象 //con(typeof ldh); con); con(ldh['sex']; ldh.sing('冰雨'); ------------------- var zxy = new Star('张学友', 19, '男'); con); con); zxy.sing('吻别');
注意:
1,构造函数名字首字母要大写。
2,我们构造函数不需要return,就可以返回结果。
3,我们调用构造函数,必须用new
4,我们只要new Star() 调用函数就创建一个对象。如ldh {}
5,我们的属性和方法前面必须添加this 。
为啥要用this. 因为对象一定是具体的事物,name不是具体事物,加个this. 就是特指这个名字,就是具体的对象了。
for in 遍历对象
//遍历对象的格式 for(变量 in 对象) { } ------------应用举例------------ for(var k in obj) { con(k);//k变量输出,得到的是属性名 con(obj[k]);//obj[k]得到的是 属性值 }
内置对象
前面讲过内置数组arguments 。 简单点说,内置对象就是自带的功能,不需要再写程序,就可以直接拿来用的。
内置对象可以在MDN上查文档,了解内置对象及其用法。
内置对象:Math对象
取两个数之间的随机整数,并且包含这两个整数:
function getRandom(min, max) { return Ma(Ma()*(max-min + 1))+ min); } con(getRandom(1, 10));
内置对象:Date对象
因为Date是构造函数(因为这个函数名的首字母是大写的,所以是构造函数),必须用new之后才能使用。
//Date()日期对象。 是一个构造函数。 //必须使用new 来调用创建我们的日期对象 var arr = new Array();//创建要给数组对象 var obj = new Object();//创建一个对象实例 //1,使用Date 如果没有参数,返回所用电脑设备的当前时间 var date = new Date(); con(date); /*2,参数常用的写法: 数字型 2019,10,01 字符串型 '2019-10-1 8:8:8'*/ var date1 = new Date(2019,10,1); con(date1);//返回的是11月,不是10月,有点特殊 var date2 = new Date('2019-10-1 8:8:8'); con(date2);
日期格式化
我们想要2019-8-8 8:8:8格式的日期,要怎么办呢?
需要获取日期指定的部分,所以我们要手动得到这种格式。
//格式化日期 年月日 var date = new Date(); con());//输出当前的年份 2020 con() + 1);//输出当前月份 //getMonth给的年份比实际年份小1个月 记得月份+1哦 con());//输出当前是几号 con());//当前是周五,输出值是5 //周日对应0 周一对应1 ...周六对应6 ------------------------ //案例:写一个输出值为2020年4月24日 星期五 var year = da(); var month = da() + 1; var dates = da(); var arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六']; var day = da(); con('今天是' + year + '年' + month + '月' + dates + '日' + arr[day]);
//格式化 时分秒 var date = new Date(); con());//时 con());//分 con());//秒 //案例:封装一个函数 输出当前的时分秒 格式08:08:08 function getTimer() { var time = new Date(); var h = (); h = h < 10 ? '0' + h : h; var m = (); m = m < 10 ? '0' + m : m; var s = (); s = s < 10 ? '0' + s : s; return h + ':' + m + ':' + s; } con(getTimer());
//获得Date总的毫秒数 不是当前时间的毫秒数 //而是距离1970年1月1号过了多少毫秒 //1,通过valueOf() getTime() var date = new Date(); con()); //就是我们当前时间 距离1970.1.1 总的毫秒数 con(getTime()); //2,简单的写法(最常用的写法) var date1 = +new Date(); //+new Date() 返回的就是总的毫秒数 con(date1); //3,H5新增的 获得总的毫秒数 con());
京东活动倒计时案例:
Array对象
//创建数组的两种方式 //1,数组字面量创建 var arr = [];//创建了一个空数组 var arr1 = [1,2,3];//创建时可以直接赋值。 con(arr[0]); //1,new Array() 和创建对象很像 var arr2 = new Array();//创建了一个空数组 var arr3 = new Array(2);//创建了一个数组长度为2的数组 //也就是说,里面有2个数组元素 var arr3 = new Array(2,3); //等价于[2,3] 这样写表示 里面有2个数组元素,是2和3 con(arr3);
怎么检测是否为数组
方法1,instance of arr
方法2: Array.isArray(arr)
添加/ 删除数组元素的方法
//添加 删除数组元素的方法 //1,push() 在数组的末尾 添加一个或者多个数组元素 var arr = [1,2,3]; con(4,'pink'));//5 con(arr);//[1, 2, 3, 4, "pink"]; ------------------ //2,unshift()在数组开头添加一个或者多个数组元素 con('red', 'purple'));//7 con(arr);//["red", "purple", 1, 2, 3, 4, "pink"] ------------------ //3,pop()它可以删除数组的最后一个元素 con());//pink con(arr);//["red", "purple", 1, 2, 3, 4] ------------------- //4,shift()它可以删除数组的第一个元素 con());//red con(arr);//["purple", 1, 2, 3, 4]
数组排序
//1,翻转数组 var arr = [1,2,3,4]; con());//[4, 3, 2, 1] con(arr);//[4, 3, 2, 1] //2,数组排序(冒泡排序) var arr1 = [13,4,77,1,7]; arr1.sort(function(a,b) { //return a - b;让数组按照升序的顺序排序 return b - a;//让数组按照降序的顺序排序 }); con(arr1);//[77, 13, 7, 4, 1]
返回数组元素索引号的方法
//用 indexOf(数组元素) //意思是返回该数组元素的索引号 从前往后查找 //它只返回第一个满足条件的索引号 //它如果在该数组里面找不到该数组元素,则返回 -1 var arr = [1,3,4,1,9]; con(1));//0在这里插入图片描述
//封装一个去重的函数unique 独一无二的 //var arr = ['c','a','z','a','x','a','x','c','b']; function unique(arr) { var arr1 = []; for(var i = 0; i < arr.length; i++) { i(arr[i]) === -1) { arr1.push(arr[i]); } } return arr1; } var demo = unique(['c','a','z','a','x','a','x','c','b']); con(demo);//["c", "a", "z", "x", "b"]
数组转换为字符串
//1,toString() 将我们的数组转换为字符串 var arr = [1,2,3]; con());//1,2,3 //2,join('分隔符') con());//1,2,3 con('-'));//1-2-3 con('&'));//1&2&3
连接 截图 删除 数组元素
//1,concat() var arr = [1,2,3,4,5]; var arr1 = [6,7]; con(arr1));//[1, 2, 3, 4, 5, 6, 7] con(0,2));//[1, 2] con(2,2));//[3, 4] con(arr);//[1, 2, 5] var arr1 = [5,6,7,8,9]; arr1.splice(2,0,10); document.write(arr1);//5,6,10,7,8,9 con(arr1);//[5, 6, 10, 7, 8, 9]
字符串对象
基本包装类型
字符串的不可变
指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间。
var str = 'abc'; str = 'hello'; //当重新给str赋值的时候,常量'abc‘不会被改变,依然在内存中 //重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变 //由于字符串的不可变,在大量拼接字符串的时候会有效率问题 var str = ''; for(var i = 0; i < 10000; i++;) { str += i; } con(str); //这个结果需要花费大量时间来显示,因为需要不断的开辟新的空间
//字符串对象 根据字符返回位置 ('要查找的字符', [起始的索引号位置]) var str = '改革春风吹满地,春天来了'; con(('春');//不写起始位置,默认从头开始查找 con(('春', 3)); //从索引号是3的位置开始往后查找
indexOf()案例
var str = 'oabcoefoxyozzopp'; var index = ('o');//第一个'o'出现的位置 var num = 0; while(index !== -1) { //con(index); document.write(index); num++; index = ('o', index + 1); } //con('o出现的次数是:' + num); document.write('o出现的次数是:' + num);
根据位置返回字符(重点)
案例:返回字符位置
判断一个字符串'abcoefoxyxzzopp'中出现次数最多的字符,并统计其次数。
核心算法:
1,利用charAt()遍历整个字符串
2,把字符串里面的每个字符,都存储给对象。如果该对象没有属性(即这个字符在对象里存储的次数为0),那么次数就赋值为1,如果这个字符在对象里已经存储了,就让存储次数自增1
var str = 'avcoefoxyozzopp'; var o = {};//创建一个空对象o //遍历字符串 for(var i = 0; i < ; i++) { //chars 是字符串里的每一个字符 var chars = (i); if(o[chars]) {//如果o对象里还没有存储这个chars属性(即字符) o[chars]++;//那么这个chars字符存储的字数就自增1 } else { //这个字符已经在o对象里还没有存储,那就让存储的次数等于1 o[chars] = 1; } } con(o);//Object {a:1 c:1 e:1 f:1 o:4 p:2 v:1 x:1 y:1 z:2} //现在每个字符都在o对象里存储了,开始遍历o对象 var max = 0; var ch = ''; for(var k in o) { //k是属性名(即存储的字符) //0[k]就是属性值,即该字符在o对象里存储的次数 if (o[k] > max) { max = o[k];//把存储的次数赋值给max ch = k;//把存储的字符赋值给ch } } con(max);//输出次数 4 con(ch);//输出该次数最多的字符 o
字符串的操作方法(重点)
//字符串操作方法 //1,concat(str1,str2,str3…) var str1 = 'i'; var str2 = ' love'; con(str2));// i love //2,substr(start, length) var str = "hello"; con(2,2));// ll
简单类型和复杂类型
简单类型又叫基本数据类型或者值类型,复杂类型又叫做引用类型。
值类型:简单数据类型 / 基本数据类型, 在存储时变量中存储的是值本身,因此叫做值类型。
如,string , number , boolean , undefined , null
但是null比较特殊。 null类型返回的是一个空对象。
var timer = null; con(typeof timer);// object /*如果有个变量我们以后打算存储为对象, 但是暂时又没想号放啥,这个时候就可以给null*/
引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型。
通过new关键字创建的对象,如Object,Array,Date等,都是引用类型。
堆和栈(了解)
简单类型传参
函数的形参也可以看作是一个变量,当我们把一个值类型作为参数传给函数的形参时,其实是把变量在栈空间的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到它的外部变量。
通俗的讲,就是形参就是一个可以改变的参数,不管怎么改,在传来实参的时候,都不影响函数的调用。
function fn(a) { a++; con(a); } var x = 10; fn(x); con(x);
复杂类型(引用类型)传参
函数的形参也可以看作是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。 形参也是可以操作对象的,而且是和实参操作了同一个对象。
function Person(name) { = name; } function f1(x) { con('1,' + x.name);//实参p把name 刘德华 传给了形参 x.name = "张学友";//给形参赋值 con('2,' + x.name);//对形参输出 } var p = new Person("刘德华"); con('3,' + p.name);//刘德华 f1(p); con('4,' + p.name);//实参操作了形参对应的对象,输出等同于x.name /* 3,刘德华 1,刘德华 2,张学友 4,张学友 */
学到这里。js的第一部分 即 ECMAScript就学完了。
-------------------------------------------------
Web APIs 的学习:即 DOM 和BOM
web apis 和 js 的基础关联性
js基础阶段以及web apis阶段
JS 基础学习 ECMAScript 基础语法为后面做铺垫,Web APIs 是 JS 的应用,大量使用 JS基础语法做交互效果。
API 和 Web API
API:应用程序接口
Web API:浏览器提供的应用程序接口
DOM(文档对象模型)
DOM是什么?
DOM树:
文档:一个页面就是一个文档,DOM中使用document表示。
元素:页面中的所有标签都是元素,DOM中使用element表示。
节点: 网页中的所有内容都是节点(标签、属性、文本、注释、空格等),DOM中使用node表示。
DOM把以上所有内容都看作是对象。
DOM如何获取元素
DOM如何获取页面元素
根据ID获取 document.getElementById()
根据标签名获取 document.getElementByTagName()
通过HTML5新增的方法获取
特殊元素获取
根据ID获取
使用 getElementById() 方法可以获取带有ID元素的对象。
<body> <div id="time">2019-9-9</div> <script> //1,因为我们文档页面是从上往下加载,所以先得有标签,所以我们的script写到标签的下面。 //2,get获得element 元素 by 通过 驼峰命名法 //3,参数 id 是大小写敏感的字符串 //4,返回的是一个元素对象 var timer = document.getElementById('time'); con(timer); con(typeof timer); //5,con 打印我们返回的元素对象,更好的查看里面的属性和方法 con(timer); </script> </body>
根据标签名获取
使用document.getElementByTagName()方法可以获取带有指定标签名,的对象的集合。 使用语法: document.getElementByTagName('标签名');
注:这里不一定要用document,还可以用标签名或ID等元素。可以获取某个标签里面的一些标签。 如果是获取了多个元素,Element要加s 。
<body> <ul> <li>2333</li> <li>2333</li> <li>2333</li> <li>2333</li> </ul> <ul id="nav"> <li>666</li> <li>666</li> <li>666</li> <li>666</li> </ul> <script> //1,返回的是 获取过来的元素对象集合 以伪数组的形式存储的 var lis = document.getElementsByTagName('li'); con(lis); con(lis[0]); //2,我们想要依次打印里面的元素,我们可以采取遍历的方式 for(var i = 0; i < lis.length; i++) { con(lis[i]); } //3,element.getElementsByTagName() 可以得到这个元素里面的某些标签 var nav = document.getElement('nav'); var navLis = nav.getElementByTagName('li'); con(navLis); </script> </body>
通过HTML5新增的方法获取元素
根据类名来获取。
但是要注意,这个方法值支持ie9以上的浏览器版本。
document.getElementsByClassName(‘类名’);
document.querySelector( ’ 选择器 ’ );
document.querySelectorAll(‘选择器’);
第2个和第3个获取元素方式,选择器必须带符号。类的选择器就加’ . ',ID选择器就加个#
获取特殊元素(body , html )
获取body元素
document.body //返回body元素对象
获取html元素
document.html // 返回html元素对象
事件基础
1. 谁发生 2. 怎么发生 3. 发生什么
<body> <button id="btn">唐伯虎</button> <script> //点击一个按钮,弹出对话框 //1,事件是由三部分组成 事件源 事件类型 事件处理程序 我们也称为事件三要素 //(1)事件源 就是 谁发生 --按钮 //谁发生就把谁获取过来,先获取再操作 var btn = document.getElementById('btn'); //(2)事件类型 怎么发生 比如鼠标点击 //(3)事件处理程序 发生什么 //通过一个函数赋值的方式完成,发生的内容都在函数里 b = funtion() { alert('点秋香'); } //谁发生 btn //怎么发生 onclick //发生什么 alert </script> </body>
常见的鼠标事件(怎么发生)
mouseenter 和 mouseover 的区别
mouseenter不会冒泡。
可以这样理解: