目录
1.3.5 boolean型以及undefined和null
10.4 统计字符串中出现次数最多的字符,并写出次数(案例)
>>>>>>>
1 js基础
1.1 概述
(1)js是什么
(2)js的作用
(3)浏览器执行js简介
(4)js的组成
- ecmaScript
- dom文档对象模型(把文档中的各个内容变容编译为对象)
- dom浏览器对象模型(把浏览器的各个内容编译为对象)
(5)js的书写位置
行内、内嵌和外部。
外链式:
(6)js注释
a、单行注释 //注释内容
b、多行注释 /* 多行注释内容 */
(7)js输入输出语句
a、prompt(info输入)输入框
b、alert(msg输出)弹出警示框
c、console.log(msg输出)控制台输出,给程序员测试的——浏览器调试工具处console(控制台、打印)。
每行设置;代表一行代码的结束
1.2 变量
(1)通俗概念:存放数据的容器,通过变量名获取数据,甚至数据可以修改。
(2)本质:变量是程序在内存中申请的一块用来存放数据的空间。
(3)变量的使用:
- 声明变量: var(variable可变的) 变量名 (在内存中声明一个空的空间);
- 赋值 age = 值;
- 变量的初始化(声明变量并赋值)var age = 值;
(4)变量语法扩展
更新变量:一个变量被重新赋值后,它原有的值会被覆盖,以最后一次赋的值为准。
重新赋值时不用再次声明,只用赋值就可以;
声明多个变量用逗号隔开,var 变量名1 = 值,变量名2 = 值(也可以先不赋值);
声明变量的特殊情况
①声明不给值:
打印:undefined(未定义的);
②未声明 未赋值直接使用某个变量
打印:报错(”xxx is not defined“);
③未声明,只赋值
打印:正常使用(不提倡)。
(5)变量的命名规范
关键词和保留字:在js中有一定功能的单词
分析:规定(必须遵守):1234条,以及不能用name(使用后会让赋的值变为字符串)和top命名。
规范(尽量遵守):5(下划线隔开单词也可以)67条
(6)交换变量的值
var num1 = 10;
var num2 = 20;
var blank = num1; //把右边给左边
num1 = num2; num2 = blank;
1.3 数据类型
(1)概念:不同的数据类型,占据不同的存储空间。
(2)变量的数据类型:
js的变量数据类型是只有程序在运行过程中,根据等号右边的值来确定的。
js拥有动态类型,同时也意味着相同的变量,数据类型是可以变化的。
(3)简单数据类型(基本数据类型)
1.3.1 数字型Number
①js中数字类型既可以包括整型,也可以包括小数型(浮点型)
010(0开头表示八进制 0-7)
0x9(0x开头表示十六进制,0-9 a-f)
0b(0b开头表示二进制,0-1)
②数字型范围:
③数字型三个特殊值:
当数学运算产生不了正确的结果时候,会产生NaN
1.3.2 isNaN()
这个方法用来判断非数字,并且返回一个值,如果是数字返回false,如果是数字返回ture。
1.3.3 符串型String
①字符串型可以是引号中的任何文本,可以是’ ‘也可以是” “。推荐使用单引号。
字符串型有嵌套规则,外单内双,外双内单
Unexpected identifier格式错误(无法识别的标识符)
②字符串的转义符
都是用\开头,且必须写在引号的里面
1.3.4 字符串长度以及拼接
字符串长度:length属性检测获取,var str = ’my name is andy‘; console.log(str.length); //显示12
字符串的拼接:字符串 + 任何类型 = 新的字符串
console.log (11 + 12 + '13');//"2313"结果
变量不要写在字符串里,用+相加
1.3.5 boolean型以及undefined和null
①布尔型 true和false
布尔型true参与数学运算当1看待,false当0看待
②如果一个变量声明为赋值,就是undefined未定义类型。a
undefined和字符串相加,结果是undefined字符串;
undefined和数字相加,结果是NaN;
③null 空值
空值加字符串,----null字符串
空值加数字-------原先的数字
1.4 获取变量类型
typeof空格加变量名。
typeof null结果是object
prompt("")输入的值取过来是字符型
1.5 字面量
数据的格式特征,通过这种格式就能判断是哪种数据类型
1.6 数据类型的转换
(把一种数据类型的变量转换成另外一种数据类型)
1.6.1 转换为字符串型
①var num = 10;
var str = num.toString();
②String(转换对象);
③利用加号拼接字符串的方法。
num + ” “;
- toStringh 和String使用方式不同
- 第三种方法更常用,也称为隐式转换
- 空字符串 ” “长度是零
1.6.2 转换为数字型
①parseInt和parseFloat,整数型和浮点型的转换。
语法格式:parseInt(转换的对象)
parseInt("") //NaN
转换小数时得到的结果是整数,console.log(parseInt("3.14")); //3取整 console.log(parseInt("120px")); //120会去除px这个单位。从第一个字符开始,找第一个数字,否则结果时NaN
和parseFloat(转换的对象)
转换可得到小数(浮点数),转换整数时依旧时整数,用法与上面基本相似。
②利用Number(转换的对象)
var str = “123”;console.log(Number(str));
③利用算数运算(隐式转换)- / *(不用加号)
console.log('12' - 0); //12
console.log('123' - '120') //3
1.6.3 转换为布尔型
!!转换的对象,也可以转换布尔值
2 运算符概括
2.1 算术运算符
(1) 运算符与数字之间加空格
(2) + - * / %(取余)
浮点数计算时误差原因:小鼠转换为二进制再转换为十进制时产生误差,所以其计算精度永远不如整数
我们不能直接拿浮点数来进行比较,因为误差原因,结果可能不相等
(3) 表达式和返回值
- 表达式:由数字、运算符、变量以求所得数值的有意义排列方法所得的组合;
- 返回值:就是得到的结果
在程序中由右边表达式计算出来,返回赋值给左边
2.2 前置递增运算符和后置递增运算符
(1) 前置递增运算符(先运算,后把值返回(前置--直接开算))
++num前置递增,相当于num = num + 1 ;
先自加1,后返回值
前置递增相当于 num = num + 1;中第一个num,后置递增相当于第二个num,无论前置后置,都会使num自加1,需要注意表达式与num不同,num++和num不相同
递增符只能放在变量的前面,无法放在一个数字前
(2) 后置递增运算符(先返回值,后运算(后置--后面再算))
num++,相当于num = num + 1;
先返回值,后自加1
(3) 两者的异同
- 单独使用时,两者没有区别,都是给变量加一
- 前置先自加1,后返回值,后置先返回值,后自加1。
var p = 10;
console.log(++p + 10); //21
console.log(p++ + 10); //20
(4) 自减运算符(与自加特性基本相同)
2.4 比较运算符
(1) == (只要求数值相同)
10 == '10';//true
(2) === 和 !==
全等于和不全等,===需要前后比较的值和数据类型完全一致才行。
(3)不要连续比较多个数字
console.log (13 < 4 < 5); //true
(13与4先进行比较得到false,之后false和5进行比较,false在运算中相当0)
2.5 逻辑运算符
(1) 逻辑&&(与)
逻辑与 两侧都是true结果才是true,只要一侧false,结果就是false。
(2) 逻辑或|| or
两侧只要有一个true就是true,两侧都为false结果才是false。
(3) 逻辑非 ! not (!true ----false)也称取反符
2.6 逻辑中断(段落运算)
(1) 原理:左边的表达式可以确定结果时,就不再继续运算右边表达式的值
(2) 逻辑&&与的逻辑中断
表达式参与逻辑运算console.log(表达式1&&表达式2);
- 如果表达式1结果为真,则返回表达式2
- 如果表达式1结果为假,则返回表达式1
var re = 10;
var r = 1 && (re = 20);
console.log(r); //20 (逻辑与返回值为20,赋给r)
如果有空或者否定的为假( 0 "" null undefined),其余为真
(2) 逻辑||或
- 如果表达式1结果为假,则返回表达式2
- 如果表达式1结果为真,则返回表达式1
返回值时,返回的都是可以决定整体真假的那个表达式的值,式子真假也是依据可判断整体结果的式子
2.7 赋值运算符
var age = 2;赋值表达式返回的值是等号右边的值
age *= 3; //6
2.8 运算的优先级
比较运算符:先不等(><)再相等(= !=)
逻辑运算中,返回的值是式子的返回值
2.9 流程控制
2.1 顺序结构
顺序结构:代码的先后顺序,一次执行(默认)
2.2 分支结构
由上到下执行代码的过程中,根据不同的条件,执行不同的路径代码,从而得到不同的如果
2.2.1 if分支语句
(1) 语法结构:
if (条件表达式) {
执行语句;
} else {
执行语句;
}
(2) 执行思路
如果if里面的条件表达式结果为真true,则执行大括号里面的,执行语句
如果if的条件表达式为假,则不执行大括号里面的语句,执行else里的语句
(3) 注意点和总结
比较大小时,不推荐直接用字符串进行比较
字符串进行比较时,会依次对从字符的第一个开始比较,相等后向后比较
if和else中的语句,最终只会且一定有一个被执行。else后直接跟大括号
2.2.2 多分支语句
注意点:
①多分支语句还是多选一个,最后只能有一个语句被执行;
②else if里面的条件理论上可以时无穷多个;
③else和if之间有个空格;
④else条件可以不写。
2.2.3 三元表达式
(1) 有三元运算符组成的式子,我们称为三元表达式。
(2) 条件表达式? 表达式1: 表达式2;
(3) 执行思路
如果条件表达式的结果为真,则返回表达式1的值,如果为假,则返回表达b式2的值
(4) 例子
2.2.4 switch语句
(1) switch语句也是多分支语句,也可实现多选1
(2) 语法结构
switch(表达式){
case value1:
执行语句1;
break;
case value2:
执行语句1
break;
...
default:
执行最后的语句;
}
(3) 执行思路
利用我们表达式的值和case后面的选项值匹配,如果匹配上,就执行该case的执行语句,如果都没匹配上,则执行default里面的语句。
(4) 注意点
switch(表达式),表达式的经常是个变量
switch中表达式和case的值匹配时,必须时===
break可以不写,但不写会使当前switch不结束,继续执行下一个case,直到遇到break
2.2.5 switch和if else if的区别
- 一般情况下,他们两个语句可以相互替换。
- switch...case语句通常用于值比较固定的情况,而if...else if 更加灵活。
- switch进行条件判断后直接执行到程序的条件语句,而if会逐条判断,
- 当分支少时,if语句少相对效率高
- 当分支多时,switch结构清晰,直接定位效率高。
switch 和 if else if的替换。
3 循环导读
(1) 目的:为了重复执行某些代码。
(2) js中的循环: for循环,while循环,do while循环。
3.1 for循环
3.1.1 概念
for重复执行某些代码,通常跟计数有关系。
3.1.2 语法结构
for(初始化变量;条件表达式;操作表达式) {
//循环体
}
(1) 初始化变量 就是用var声明的一个普通变量,通常用于作为计数器使用。
(2) 条件表达式 就是用来每一次循环是否继续执行,就是终止的条件
(3) 操作表达式 是每次循环最后执行的代码,经常用于我们计数器变量进行更新(递增或递减)
3.1.3 代码体验 我们重复打印100句,你好
for(var i = 1;i <= 100;i++) {
console.log('你好');
}
3.1.4 for 循环执行过程。
var i = 1;(只执行一次 index)——i <=100;(去这来判断是否满足条件,满足就执行,不满足就退出)——//循环体——i++;——i <= 100;——//循环体...
3.1.5 断点调试
注意:
- 如果观察被选择的变量、表达式1,鼠标悬停在变量上
- 如果观察表达式、变量2,复制表达式在右边watch中
3.1.6 for循环代码案例
(3)一行打印n个星星
var str = '';
var num = prompt ('你想打印几个星星');
for (i = 1; i <= num; i++) {
str += '★'
}
console.log (str);
3.1.7 双循环语句(循环嵌套)
(1) 语法结构
for (外层的初始化变量;外层的条件表达式;外层的操作表达式) {
for (里层的初始化变量;里层的条件表达式;里层的操作表达式){
//执行语句
}
}
(2) 我们可以把里面的循环看作是外层循环的语句
(3) 外层循环一次,里层循环全部。
3.2 while循环
3.3 do while循环
注do while至少执行一次循环体代码
3.4 循环小结
3.5 continue和break关键字
3.5.1 continue关键字:
立即跳出本次循环,继续下一次循环。
(1) 代码
for (var i = 1;i <= 5; i++) {
if (i == 3) {
continue;// 只要遇见continue就退出本次循环,直跳到i++。
}
console.log('我正在吃' + i + '个包子');
}
(2) 求1-100之间,除了能被7整出之外的整数和。
当执行的代码在continue之前,仍会被执行
3.5.2 break关键字
break关键字立即退出整个循环。
当执行的代码在break之前,仍会被执行,但后续不执行
3.6 js命名规范和语法格式
3.6.1 标识符命名
4 数组
4.1 概念
数组就是一组数据的集合,存储在单个变量下的优雅方式。
4.2 创建数组
(1)利用new创建数组
var arr = new Array();// 创建了一个空的数组。
(2)利用数组字面量创建数组[]
var arr = [] //创建了一个空的数组。
注:
- 数组之间的数据一定用,隔开
- 数组里面的内容为数组元素
4.3 获取数组元素
(1)数组的索引
用来访问数组元素的序号,从零开始
利用数组元素从左到右排序,0 1 2 3 4。
(2)获取
数组名[索引号]得到数组元素
4.4 遍历数组
把数组元素全部取出来:
遍历:就是把数组中的每个元素从头到尾访问一次。
因为数组索引号从0开始,所以i必须从0开始。
输出的时候arr[i],i计数器当索引号来用
4.5 获取数组中元素的个数
数组名.length可以获取数组中元素的个数。
数组的长度数元素的个数,不要跟索引号混淆(从零开始)
arr.length动态检测数组元素的个数
注:倒续的遍历的输出:for(var i = arr.length - 1;i >= 0 ;i--)
{
console.log(arr[i]);
}
console.log想要输出多个变量,用,分隔即可
4.6 数组中的最大数(案例)
var arr = [2,6,1,77,52,25,7];
var max = arr[0];
for (var i = 1; i < arr.length; i++ ) {
if (arr[i] > max) {
max = arr[i];
}
}
console.log ('数组中的最大值是:' + max);
4.7 数组中新增元素
(1)通过修该length长度新增数组元素
var arr = ['red', 'green', 'blue'];
console.log(arr.lemgth);
arr.length = 5; // 把我们数组中的元素修改为了5
console.log (arr[3], arr[4]); // undefined
(2)新增数组元素,修改索引号
var arr1 = ['red', 'green', 'blue'];
arr1[3] = 'pink'; //新增pink
arr1[4] = 'hotpink'; //新增hotpink
arr1[0] = 'yellow';
已有的数组[索引号]是替换,未有的是添加
最好不要直接给数组名赋值,否则里面的数组元素都被替换
如果数组[索引号]赋值过大,会产生空位置
arr[arr.length] = '';可以保证自动添加,且没有空位置
4.8 反转数组(案例)
方法一
方法二
4.9 冒泡排序(锻炼思维案例)
智能减少循环次数:
5 函数
5.1 概念
就是封装了一块可以被重复执行调用的代码块(为了让大量代码更快捷的被重复使用)
5.2 函数的使用
(1)声明函数
function 函数名() {
//函数体
}
function声明的函数的关键词,都是小写
函数是做某件事情,函数名一般是动词
函数不调用自己不执行
5.2.1 调用函数————————函数名();
调用函数时别忘记小括号
5.2.2 函数的封装
就是把一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
5.2.3 函数的参数(可以让函数有不同的变化)
多个参数用逗号隔开
(1)形参和实参
function 函数名(形参1,形参2...){//在声明函数的小括号里面是形参(形式上的参数)
}
函数名(实参1,实参2);
//在函数调用的小括号里面是实参(实际的参数)
实参可以是一个数组,对象,函数。。。相当 形参 = 实参;
(2)执行过程
function cook(aru){ // 形参是接受实参的, aru = '傻逼' 形参类似于一个变量,接受实参的值。
console.log(aru);
}
cook('傻逼');
(3)函数的参数可以有,也可以没有,个数没有限制。
5.2.4 函数的参数的匹配问题
(1)个数不匹配时
实参的个数大于形参时:
会取到形参的个数,多余不计
如果形参的个数大于实参的个数:
形参可以看作只声明的变量但不会被前面调用函数时影响赋值
多余的形参会定义为undefined
函数在声明的时候,可以给形参设置默认值(变量赋值的形式)
5.2.5 函数的返回值return
(1)格式
function 函数名(){
return 需要返回的结果;
}
(2)调用
函数名();
我们函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名(),通过return实现的
只要函数遇到return就把后面的结果,返回给函数的调用者,函数名() = return后面的结果
(3)代码验证
function getResult (aru) {
return aru;
} console.log(getResult('shabi')); // 相当于函数是个表达式,返回值为他得到的结果。
为什么不在函数内部打印:为了得到返回值,方便后续运算
无论函数内部代码如何执行,有无结果,调用者只等于return返回值
(4)return终止函数
return之后的代码不会被执行,所以return应放在函数的最后
return只能返回一个值 // return 1,2;只返回最后一个值2。
可以用数组实现返回多个值的目的
(5)如果函数有return,则返回return,没有则返回undefined
(6)break,continue,return的区别
函数的return未写数据时,返回值时undefined
5.3 arguments
(1)作用
自动存储函数调用的时候传入的实参
(2)需要声明吗
不需要声明,只需要函数中使用就可以了
(3)如何使用
arguments本质是一个伪数组
通过索引值可以获取arguments中存储的数据
通过length获取arguments中数据的数量
函数可以相互调用
6 作用域
6.1 作用域概述
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
*也就是变量的使用范围*
JavaScript(es6前)中的作用域有两种:
-
全局作用域
-
局部作用域(函数作用域)
6.2 全局作用域
作用于一个文档的内部。
6.3 局部作用域
作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域。
6.4 JS没有块级作用域
-
块作用域由 { } 包括。但{}不能划分除作用域
-
在其他编程语言中(如 java、c#等),在 if 语句、循环语句中创建的变量,仅仅只能在本 if 语句、本循环语句中使用,如下面的Java代码:
java有块级作用域:
if(true){ int num = 123; system.out.print(num); // 123 } system.out.print(num); // 报错
以上java代码会报错,是因为代码中 { } 即一块作用域,其中声明的变量 num,在 “{ }” 之外不能使用;
而与之类似的JavaScript代码,则不会报错:
Js中没有块级作用域(在ES6之前)
if(true){
var num = 123;
console.log(123); //123
}
console.log(123); //123
6.5 变量的作用域
在JavaScript中,根据作用域的不同,变量可以分为两种:
-
全局变量
-
局部变量
6.6.1 全局变量
在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。
-
全局变量在代码的任何位置都可以使用
-
在全局作用域下 var 声明的变量 是全局变量
-
特殊情况下,在函数内不使用 var 声明的变量也是全局变量(不建议使用)
6.6.2 局部变量
在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)
-
局部变量只能在该函数内部使用
-
在函数内部 var 声明的变量是局部变量
-
函数的形参实际上就是局部变量
6.6.3 全局变量和局部变量的区别
-
全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存
-
局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间
6.7 作用域链
只要是代码都一个作用域中,写在函数内部的局部作用域,未写在任何函数内部即在全局作用域中;如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域;根据在**[内部函数可以访问外部函数变量]**的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链
一种变量的查找规则
案例分析1:
function f1() {
var num = 123;
function f2() {
console.log( num );
}
f2();
}
var num = 456;
f1();
函数调用时,只看最外部的调用,即使外部函数中调用内部函数,也不执行,只有外部执行时随外部执行
作用域链的规则:
- 先从当前作用域查找该变量
- 如果当前作用域没有该变量,则一次向上层作用域总查找该变量
- 如果一直未查找到
如果时取值操作,则报错
如果时赋值操作,则把当前变量设为全局变量(不推荐使用的全局变量声明方式)
作用域链:采取就近原则的方式来查找变量最终的值。
var a = 1;
function fn1() {
var a = 2;
var b = '22';
fn2();
function fn2() {
var a = 3;
fn3();
function fn3() {
var a = 4;
console.log(a); //a的值 ?
console.log(b); //b的值 ?
}
}
}
fn1();
6.8 预解析
6.8.1 预解析的相关概念
JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析和代码执行。
-
预解析:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 var 和 function 声明的变量在内存中进行提前声明或者定义,也称声明提升。
-
任何作用域中的代码开始执行之前,都会进行预解析
-
代码执行: 从上到下执行JS语句。
预解析会把变量和函数的声明在代码执行之前执行完成。且先声明var,再声明function
6.8.2 变量预解析
预解析也叫做变量、函数提升。
变量提升(变量预解析): 变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。
console.log(num); // 结果是多少?
var num = 10; // ?
结果:undefined
注意:**变量提升只提升声明,不提升赋值**
6.8.3 函数预解析
函数提升: 函数的声明会被提升到当前作用域的最上面,但是不会调用函数。
fn();
function fn() {
console.log('打印');
}
结果:控制台打印字符串 --- ”打印“
注意:函数声明代表函数整体,所以函数提升后,函数名代表整个函数,但是函数并没有被调用!
6.8.4 函数表达式声明函数问题
函数表达式创建函数,会执行变量提升,此时接收函数的变量名无法正确的调用:
fn();
var fn = function() {
console.log('想不到吧');
}
结果:报错提示 ”fn is not a function"
解释:该段代码执行之前,会做变量声明提升,fn在提升之后的值是undefined;而fn调用是在fn被赋值为函数体之前,此时fn的值是undefined,所以无法正确调用
7 对象
7.1 对象的相关概念
-
什么是对象?
在 JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。 对象是由属性和方法组成的。 提供更好的存储数据的方式。
-
属性:事物的特征,在对象中用属性来表示(常用名词)
-
方法:事物的行为,在对象中用方法来表示(常用动词)
-
-
为什么需要对象?
保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组。 如果要保存一个人的完整信息呢? 例如,将“张三疯”的个人的信息保存在数组中的方式为:
var arr = [‘张三疯’, ‘男', 128,154];
上述例子中用数组保存数据的缺点是:数据只能通过索引值访问,开发者需要清晰的清除所有的数据的排行才能准确地获取数据,而当数据量庞大时,不可能做到记忆所有数据的索引值。 为了让更好地存储一组数据,对象应运而生:对象中为每项数据设置了属性名称,可以访问数据更语义化,数据结构清晰,表意明显,方便开发者使用。 使用对象记录上组数据为:
var obj = { "name":"张三疯", "sex":"男", "age":128, "height":154 }
JS中的对象表达结构更清晰,更强大。
7.2 创建对象的三种方式
-
利用字面量创建对象
使用对象字面量创建对象:
就是花括号 { } 里面包含了表达这个具体事物(对象)的属性和方法;{ } 里面采取键值对的形式表示
-
键:相当于属性名
-
值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等)
代码如下:
var star = { name : 'pink', age : 18, sex : '男', sayHi : function(){ alert('大家好啊~'); } };
上述代码中 star即是创建的对象。
不同的对象可以有相同的属性、方法
-
-
对象的使用
-
对象的属性
-
对象中存储具体数据的 "键值对"中的 "键"称为对象的属性,即对象中存储具体数据的项
-
-
对象的方法
-
对象中存储函数的 "键值对"中的 "键"称为对象的方法,即对象中存储函数的项
-
-
访问对象的属性
-
对象里面的属性调用 : 对象.属性名 ,这个小点 . 就理解为“ 的 ”
-
对象里面属性的另一种调用方式 : 对象[‘属性名’],注意方括号里面的属性必须加引号
示例代码如下:
console.log(star.name) // 调用名字属性 *console.log(star['name'])* // 调用名字属性
-
-
调用对象的方法
-
对象里面的方法调用:对象.方法名() ,注意这个方法名字后面一定加括号
示例代码如下:
star.sayHi(); // 调用 sayHi 方法,注意,一定不要忘记带后面的括号
-
-
变量、属性、函数、方法总结
属性是对象的一部分,而变量不是对象的一部分,变量是单独存储数据的容器
-
变量:单独声明赋值,单独存在
-
属性:对象里面的变量称为属性,不需要声明,用来描述该对象的特征
-
-
方法是对象的一部分,函数不是对象的一部分,函数是单独封装操作的容器
- 函数:单独存在的,通过“函数名()”的方式就可以调用
- 方法:对象里面的函数称为方法,方法不需要声明,使用“对象.方法名()”的方式就可以调用,方法用来描述该对象的行为和功能。
-
利用 new Object 创建对象
-
创建空对象
var andy = new Obect();
通过内置构造函数Object创建对象,此时andy变量已经保存了创建出来的空对象
对象.属性名 = 属性值时,属性名已经存在时,新属性值会覆盖掉旧属性值
-
给空对象添加属性和方法
-
通过对象操作属性和方法的方式,来为对象增加属性和方法
示例代码如下:
andy.name = 'pink'; andy.age = 18; andy.sex = '男'; andy.sayHi = function(){ alert('大家好啊~'); }
注意:
-
Object() :第一个字母大写
-
new Object() :需要 new 关键字
-
使用的格式:对象.属性 = 值;
-
-
-
利用构造函数创建对象
-
构造函数
-
构造函数:是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面,批量创建对象的函数。
-
构造函数的封装格式:
function 构造函数名(形参1,形参2,形参3) { this.属性名1 = 参数1; this.属性名2 = 参数2; this.属性名3 = 参数3; this.方法名 = 函数体; }
-
构造函数的调用格式
var obj = new 构造函数名(实参1,实参2,实参3)
以上代码中,obj即接收到构造函数创建出来的对象。
-
注意事项
-
构造函数约定首字母大写(规范写法)。
-
函数内的属性和方法前面需要添加 this ,表示当前对象的属性和方法。
-
构造函数中不需要 return 返回结果。
-
当我们创建对象的时候,必须用 new 来调用构造函数。
-
-
其他
构造函数,如 Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class)创建对象的模板 创建对象,如 new Stars(),特指某一个,通过 new 关键字创建对象的过程我们也称为对象实例化 模板造出的对象
-
利用构造函数创建对象,可以理解为构造函数通过new关键词,将其中代码作为一个对象格式的返回值
-
-
-
new关键字的作用
-
在构造函数代码开始执行之前,创建一个空对象;
-
修改this的指向,把this指向创建出来的空对象
-
-
执行函数的代码
-
在函数完成之后,返回this---即创建出来的对象隐式的返回this
-
工厂函数也可以创建数组
创建一个空对象,把obj指向该对象;
给oj添加属性和方法;
返回obj。
-
当命名的属性名和属性值一样时,方法也适用,可以简写,只写一个就可以
var obj = {
username;
hi() {
console.log("hi!")
}
}
7.3 遍历对象
for...in 语句用于对数组或者对象的属性进行循环操作。 其语法如下:
for (变量 in 对象名字) {
// 在此执行代码
}
语法中的变量是自定义的,它需要符合命名规范,通常我们会将这个变量写为 k 或者 key。
for (var k in obj) {
console.log(k); // 这里的 k 是属性名
console.log(obj[k]); // 这里的 obj[k] 是属性值
}
如果直接写 obj.k,浏览器会认为是obj中叫k的属性名
且obj.k为一个整体,k无法单独看作一个变量,无法通过循环改变为对象属性名。
8 内置对象
8.1 概念
8.2 查阅MDN(推荐)/W3C文档
搜索框搜索——查看功能
查看返回值的意义和类型
8.3 Math数学对象
math对象是js中内置的数学常数和函数功能的对象, 不是一个构造函数,他是静态的,可以直接使用,无需用 new来调用。
(1)Math绝对值和三个取整方法
-
最大值最小值Math.max(), Math.min()
-
绝对值Math.abs(),碰到字符串的数字,会隐式转换为数字后取绝对值
-
取整Math.floor(),向下取整,往小了取整,Math.ceil(),向上去整,往大了取整。
-
Math.round(),四舍五入取整,大约。(四舍五入的五是往大了的取的)
(2)随机数方法Math.random(),返回一个随机的小数,零到一之间,不包括1。
这个函数返回两个数之间的整数
8.4 日期对象
(1)概念
Date是一个构造函数,可以创建日期对象,用来记录时间记录
(2)使用
new Date();
(3)传入参数
-
可以不传参数,默认记录的是当前时间信息;
-
可以传入参数,如果传入参数,记录的是参数指定的时间信息;
-
可以传入表示时间的字符串:
代码体验: var d2 = new Date(“2020-11-13 12:14:16”)(/也可以)。
-
可以传入数字
代码体验:var d3 = new Date(2021,7,12,14,15,27);
注意:如果使用数字作为参数,月份从0开始计算,2月--1
(4)获取具体的时间信息(通过日期对象调用对象的方法来获取)
-
var d = new Date();
-
获取年份 var year = d.getfullYear(); console.log(year);
-
获取月份 var month = d.getfullMonth();console.log(month);月份记得加1 从零开始
-
获取日期 var date = d.getFullDate();console.log(date);
-
获取星期 var day = d.getfullDay();console.log(day);
-
var week = {‘星期日’,‘星期’一,‘星期二’,‘星期三’,‘星期四’,‘星期五’,‘星期六’} week[day];
-
获取小时 var hours = d.getfullHours();console.log(hours);
-
获取分钟 var minute = d.getfullMinutes();console.log(Minute);
-
获取秒 var second = d.getfullSeconds();console.log(second);
(5)获取Date总毫秒数,不是当前时间的毫秒数,而是距离1970年1月1日过了多少毫秒,也叫时间戳
方法一:var date = new Date();
date.valueof() 和 date.getTime();
方法二(常用):var date1 += new Date();
方法三(H5新增)Date.now();
8.5 数组对象
(1)给数组添加新元素arr.push()和arr.unshift()
-
push()在我们数组的末尾,添加一个或者多个数组元素
var arr = [1,2,3]; arr.push(4,'pink');
① push是可以给数组追加新元素
② push()参数直接写数组元素就可以了
③ push完毕之后,返回的结果是新数组的长度
④ 原数组也发生变化
-
unshift()在我们数组的前面,添加一个或者多个数组元素
① unshift是可以给数组追加新元素
② unshift()参数直接写数组元素就可以了
③ unshift()完毕之后,返回的结果是新数组的长度
④ 原数组也发生变化
(2)pop、shift删除数组元素
-
pop()它可以删除数组中的最后一个元素
console.log(arr.pop()); //删除的那个元素
① pop是可以删除数组的最后一个元素,记住一次只能删除一个元素
② pop()没有参数
③ pop完毕之后,返回的是删除的那个元素
④ 原数组发生变化
-
shift()是可以删除数组中的第一个元素
① shift是可以删除数组的开始一个元素,记住一次只能删除一个元素
② shift()没有参数
③ shift完毕之后,返回的是删除的那个元素
④ 原数组发生变化
(3)数组排序
-
翻转排序arr.reverse();
-
数组排序(冒泡排序)arr.sort(
function(a,b){
return a - b; //升序排列
//return b - a; //降序排列
}
);
arr.sort()如果不加函数排序会出错,只看个位数排序
注释:函数也能作为实参传入形参
arr.sort内部执行过程:
fuction(a,b) {return a - b;};传入实参的过程相当于 var fn = fuction(a,b) {return a - b;};
(4)获取数组元素的索引
-
indexOf(数组元素)作用就是返回该数组元素的索引号
它只返回第一个满足条件的索引号
它如果再该数组里面找不到元素,返回-1
-
lastIndexOf是从后向前查找
(5)扩展数组对象
① splice()可以在数组中任意位置,添加、删除、插入数据
-
删除元素:
数组.splice(开始删除的索引值,删除的数量)
注意:如果没有书写删除的数量,会把后面的都删除
返回值:被删除的元素,结果是一个数组
-
添加元素
数组.splice(开始删除的索引值,删除的数量(如果写成0,可以保证添加新元素,不过添加的位置在开始删除索引值的元素之前),新元素1,新元素2...)
注意:会把新元素添加到删除的位置去;
返回值:被删除的元素,结果是一个数组。
② concat 可以拼接两个数组
-
数组1.concat(数组2);
注意:该方法不会改变原数组,会把拼接之后的结果通过返回值暴露出去。
③ slice(开始截取的索引,截取到的索引)
9 扩展
9.1 创建数组的两种方式
(1)利用数组字面量
var arr = [1,2,3];
(2)利用new Array();
-
var arr = new Array(2);//这里的2表示数组的长度为2,里面有2个空的数组元素
-
var arr = new Array(2,3);//这里的2,3表示数组有2,3元素。
数组其实是一个比较特殊的对象(属性名是数字(索引))
简单数据类型:字符串 数字型 布尔型 undefined null
复杂数据类型: 对象
随机数函数random每次调用都会产生一个新值,而将其赋值给一个变量后,可保证随机数固定
9.2 检测数据是否为数组
(1)instanceof Array运算符,它可以用来检测是否为数组
var arr = [];
console.log(arr instanceof Array); //true
注意:console.log(arr instanceof Object); //true,所以使用这个方法有一定局限性
(2)Array.isArray(参数) 推荐
console.log(Array.isArray(arr)); //true
Array.isArray优先于instanceof ,不过是h5新增方法,ie9以上才支持
9.3 数组转换为字符串
(1)toString()将我们的数组转换为字符串arr.toString();
(2)join(分隔符)把数组中的元素拼接为字符串,arr.join(-); 不写默认为逗号
10 字符串对象
10.1 基本包装类型
var str = ‘andy’;
console.log(str.length); //4(浏览器隐式做了包装为复杂类型)
字符串的包装使得字符拥有索引,和数组索引相同
就是把简单数据类型,包装成了复杂数据类型
内部实现原理:
-
把简单数据类型包装成复杂数据类型
var temp = new String(‘andy’);
console.log(temp) // {0: a, 1: n,2: d,3: y}
-
把临时变量的值,给str
str = temp;
-
销毁这个临时变量
temp = null;
new String是包装过程中独有的方法,输出temp得到一个新的对象,
10.2 字符串的不可变性
var str = ‘andy’;
str = ‘red’;
在内存中存储过的字符串,在页面关闭前不会销毁,新赋值只是在内存中重新开辟一个新空间存储新数据,原数据不销毁
因为字符串的不可变性,会使得大量拼接字符串时,非常占内存资源。
10.3 根据字符返回位置
-
indexOf、lastIndexOf和数组方法一致
字符串所有的方法,都不会修改字符串本身,操作完成返回一个新的字符串,需要一个变量来接受返回值
str.indexOf(‘要查找的字符’,[起始的位置]);找不到-1,开始查找的位置包括起始位置
-
根据位置返回字符
①charAt(index)根据位置返回字符
var str = ‘andy’;
console.log(str.charAt(3)); //d
②charCodeAt(index) 返回相应索引号的字符ASCII值,目的:判断用户按了哪个键
console.log(str.charCodeAt(0)) ;//97
③str[index] H5新增和①等效,IE8+支持(推荐)
10.4 统计字符串中出现次数最多的字符,并写出次数(案例)
对象调用了自己没有的属性得到的是undefined,给对象新增一个未赋值的属性或方法输出为空
转换为false的值:0 NaN ‘ ’ null undefined
判断某个对象是否具有某个属性的语法: 属性名 in 对象; true为具有,false为不具有
10.5 字符串的操方法
拼接字符串:concat(‘字符串1’,‘字符串2’);
截取字符串:substr(start,length) 从start开始(索引号),length为截取长度没写长度会截取索引号之后的所有
因字符串的不可变性,字符串的方法都不会改变原字符串
10.6 转换字符串和替换字符串
replace(‘被替换的字符’,‘替换为的字符’)它只会替换匹配到的第一个字符
split(‘分隔符’)把字符串转化为数组 和join相反
划分数组取决于字符串分割的字符,如果传递的是空字符串,会把字符串里的每个字符划分开,成为数组的单个元素
11 内存分配方式
1 简单数据类型和复杂数据类型
(1)简单数据类型(值类型)
null返回的是一个空的对象,object。如果有个变量我们以后打算存储为对象,暂时没想好放啥,可以用null;
简单放在栈,栈里直接开辟空间,放的都是值。
(2)复杂数据类型(引用类型)
在栈中存放地址,十六进制表示,然后这个地址指向堆中的存储数据
(3)堆和栈
简单数据类型在栈,复杂在堆。(js中其实没有堆和栈,为了好的理解)
变量之间相互赋值时,传递的是栈中的值,包括复杂类型
(4)简单数据类型传参
(5)复杂数据类型传参
特殊情况:
如果得到新的对象,obj2会指向新对象的地址,与obj的地址不同
obj2得到新对象时,生成新的地址,新的地址重新分配给obj2
数组的每一个元素都可以看作成一个单独的简单数据类型(字符串或者数字)