js基础学习笔记

目录

1 js基础

1.1 概述

1.2 变量

1.3 数据类型

1.3.1 数字型Number

1.3.2 isNaN()

1.3.3 符串型String

1.3.4 字符串长度以及拼接

1.3.5 boolean型以及undefined和null

1.4 获取变量类型

1.5 字面量

1.6 数据类型的转换

1.6.1 转换为字符串型

1.6.2 转换为数字型

1.6.3 转换为布尔型

2 运算符概括

2.1 算术运算符

2.2 前置递增运算符和后置递增运算符

2.4 比较运算符

2.5 逻辑运算符

2.6 逻辑中断(段落运算)

2.7 赋值运算符

2.8 运算的优先级

2.9 流程控制

2.1 顺序结构

2.2 分支结构

2.2.1 if分支语句

2.2.2 多分支语句

2.2.3 三元表达式

2.2.4 switch语句

2.2.5 switch和if else if的区别

3 循环导读

3.1 for循环

3.1.1 概念

3.1.2 语法结构

3.1.3 代码体验 我们重复打印100句,你好

3.1.4 for 循环执行过程。

3.1.5 断点调试

3.1.6 for循环代码案例

3.1.7 双循环语句(循环嵌套)

3.2 while循环

3.3 do while循环

3.4 循环小结

3.5 continue和break关键字

3.5.1 continue关键字:

3.5.2 break关键字

3.6 js命名规范和语法格式

3.6.1 标识符命名

4 数组

4.1 概念

4.2 创建数组

4.3 获取数组元素

4.4 遍历数组

4.5 获取数组中元素的个数

4.6 数组中的最大数(案例)

4.7 数组中新增元素

4.8 反转数组(案例)

4.9 冒泡排序(锻炼思维案例)

5 函数

5.1 概念

5.2 函数的使用

5.2.1 调用函数————————函数名();

5.2.2 函数的封装

5.2.3 函数的参数(可以让函数有不同的变化)

5.2.4 函数的参数的匹配问题

5.2.5 函数的返回值return

5.3 arguments

6 作用域

6.1 作用域概述

6.2 全局作用域

6.3 局部作用域

6.4 JS没有块级作用域

6.5 变量的作用域

6.6.1 全局变量

6.6.2 局部变量

6.6.3 全局变量和局部变量的区别

6.7 作用域链

6.8 预解析

6.8.1 预解析的相关概念

6.8.2 变量预解析

6.8.3 函数预解析

6.8.4 函数表达式声明函数问题

7 对象

7.1 对象的相关概念

7.2 创建对象的三种方式

7.3 遍历对象

8 内置对象

8.1 概念

8.2 查阅MDN(推荐)/W3C文档

8.3 Math数学对象

8.4 日期对象

8.5 数组对象

9 扩展

9.1 创建数组的两种方式

9.2 检测数据是否为数组

9.3 数组转换为字符串

10 字符串对象

10.1 基本包装类型

10.2 字符串的不可变性

10.3 根据字符返回位置

10.4 统计字符串中出现次数最多的字符,并写出次数(案例)

10.5 字符串的操方法

10.6 转换字符串和替换字符串

11 内存分配方式


>>>>>>>

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即接收到构造函数创建出来的对象。

      • 注意事项

        1. 构造函数约定首字母大写(规范写法)。

        2. 函数内的属性和方法前面需要添加 this ,表示当前对象的属性和方法。

        3. 构造函数中不需要 return 返回结果

        4. 当我们创建对象的时候,必须用 new 来调用构造函数

      • 其他

        构造函数,如 Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class)创建对象的模板 创建对象,如 new Stars(),特指某一个,通过 new 关键字创建对象的过程我们也称为对象实例化 模板造出的对象

      • 利用构造函数创建对象,可以理解为构造函数通过new关键词,将其中代码作为一个对象格式的返回值

  • new关键字的作用

    1. 在构造函数代码开始执行之前,创建一个空对象;

    2. 修改this的指向,把this指向创建出来的空对象

  1. 执行函数的代码

  2. 在函数完成之后,返回this---即创建出来的对象隐式的返回this

  3. 工厂函数也可以创建数组

    创建一个空对象,把obj指向该对象;

    给oj添加属性和方法;

    返回obj。

  4. 当命名的属性名和属性值一样时,方法也适用,可以简写,只写一个就可以

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

数组的每一个元素都可以看作成一个单独的简单数据类型(字符串或者数字)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值