1.函数(特殊的对象)
引用数据类型
(1)函数的作用
1)特定功能代码的封装;
2)用来创建对象(构造函数 => Object、Array)
(2)函数的定义
1)函数声明(函数的声明会提升):
关键字 函数名(形式参数){
函数体
返回值
}
function add(a,b){ //具名函数(有函数名)
return a+b
}
2)函数表达式(变量会提升):
var add=function(a,b){函数体;返回值} //匿名函数(没有函数名)
var a=1
var o={}
(3)函数的调用
函数名(实际参数)
window.add()
global.add()
function add(){} -->对象指向全局
var obj = {
name:'function',
setUserName:function(userName){},
getUserName:function(){}
}
obj.setUserName('tom')
obj.getUserName()
改变this的指向=> 函数名.call(obj,参数列表)
obj => this
call => 可以接受无数个参数
函数名.apply(obj,[参数数组])
obj => this
apply => 只能接受两个参数
(4)函数的作用域
1)在函数内部定义的的变量,在函数外部访问不到;
2)在函数外部定义的变量,在函数内部可以访问到,这个变量和这个函数就组成了闭包;
3)在函数内部不存在局部作用域
function test(){
if(true){
var a=1
}
console.log(a) //a=1
}
function test(){
function inner(){
if(true){
var a=1
}
}
inner()
console.log(a)
}
4)如何在函数中定义一个局部变量
let
立即执行函数 (function(){}) ()
(function(){
console.log(999)
}) ()
(5)函数在内存中的表现形式
(6)函数内部属性
形式参数只是接受参数的快捷方式,实际的参数保存在arguments中
1)参数
function add(a,b){
console.log(a,b)
}
add(1,2,3,4)
2)arguments
类数组对象,参数实际保存的地方
[1,2,3,4,5]
{'0':1,'1':2,'2':3}
3)this
this的取值和调用它的对象有关,哪个对象调用它,那么this就指向那个对象
观察函数名前面有没有对象,如果有对象,那么this指向该对象;如果前面没有对象,this指向全局对象(global(nodejs)、window)
指定this:
函数名.call(obj,参数列表)
函数名.apply(obj,[参数数组])
(7) 函数作为值、函数作为参数、函数作为返回值
1)函数作为值
var a = 3
引用传递=> var add = function(){}
var add1 = add
2)函数作为参数 (回调函数:函数作为参数)
test(1,2,function(){})
// arr forEach(function(){})
var arr=[1,2,3,4,5]
3)函数作为返回值
function add(){
return function add1(){
}
}
var a=add()
console.log(a) => 函数
(8) 值传递和引用传递
当我们使用=将这些变量赋值到另外的变量,实际上是将对应的值拷贝了一份,然后赋值给新的变量。我们把它称作值传递。
对象是通过引用传递,而不是值传递。也就是说,变量赋值只会将地址传递过去。
值传递=> var a = 2
var b = a
b=10
a不变
引用传递=> var add = function(){}
var add1 = add
2.数组
引用数据类型
数组作用:用来保存多个值,可以保存任意数据类型的值
数组也是对象,数组是以“ [] ”为界限,值与值之间用“ ,”隔开;length数组长度,数组长度是动态的
数组定义:
(1)创建
1)数组字面量
var arr=[1,2,3,4] 0:1,1:2,2:3,3:4
arr.length =>4
2) 构造函数
var arr= new Array() =>空数组[ ] =>Object
arr.length =>0
传递一个参数:给数组指定数组长度
var arr=new Array(10) => arr.length=10
传递多个参数:相当于初始化数组
var arr=new Array(1,2,3,4) => [1,2,3,4]
(2)数组的访问
数组下标,数组下标是从0开始的,一直到数组的长度-1;如果访问的数组下标超过数组长度,会返回一个undefined
arr[0] => 1
arr[1] => 2
arr[超出长度] =>undefined
var arr=['tom',12] arr[0] 0:'tom',1:12
arr[2]=true
var obj={name:'tom',age:12} obj.name 或 obj{'name'}
obj.gender='男'
给数组添加项:arr[下标]=值(任意数据类型)
删除数组项:arr.length=arr.length-1
(3)数组的遍历 (for循环、forEach)
var obj={name:'tom',age:12}
var arr=[1,2,3,4]
(4) 数组的检测
数组类型的检测:typeof
var arr=[]
typeof arr => object
判断某个值是否是数组:instanceof
arr(目标) instanceof Array =>如果arr是数组,返回true;如果arr不是数组,返回false;在同一个全局作用域下可以这么判断
Array.isArray(arr) =>判断arr是否是数组类型
(5)数组序列化 ==>转化为字符串
toString() 默认将数组的每一项使用“ , ”隔开,以字符串的形式输出
join(参数) 将数组的每一项以想要的符号分隔开,以字符串的方式输出
(6) 数组的api
栈,队列方法(改变原数组)
栈(先进后出,后进先出):
pop() 将数组的最后一项删除 返回删除的项
push() 可以接受任意数据类型,将参数逐个添加到数组末尾 返回数组长度
队列(先进先出,后进后出):
shift() 移除数组的第一项 返回被删除的项
unshift() 可以接受任意数据类型,将参数逐个添加到数组前面 返回数组长度
排序(改变原数组):
reverse() 反转数组项的顺序 返回原数组
sort()
默认顺序,先调用toString()方法,然后根据字符的序列排列
自定义排序
sort会接受一个函数作为参数,这个函数叫做比较器函数
if(a>b){
return -1;(从大到小 ) // return 1(从小到大);
}else if(a<b){
return 1; (从大到小) //return -1(从小到大);
}
截取:
concat()
数组的拼接 不改变原数组 返回副本
slice()
截取数组 不改变原数组 返回截取到的数组
slice(a) 从a开始截取,一直到数组结束
slice(a,b) 从a开始截取,一直到第b项,但不包含第b项 =>[a,b)
splice()
删除 splice(a,b) 从第a项开始删除,删除到b项,返回删除掉的项
插入 splice(a,0,b,c,d) 从第a项开始插入,插入b,c,d,返回空数组
替换 splice(a,b,11,12,13) 从第a项开始,删除b项,将11,12,13插入
索引方法:
indexof() 从数组开头向后查找,使用全等操作符,找不到该元素返回-1;找到返回数组下标。
第一个参数为要查找的项,第二个参数(可选)为索引开始位置
lastIndexOf() 从数组末尾向前查找,使用全等操作符,找不到该元素返回-1;找到返回数组下标。
第一个参数为要查找的项,第二个参数(可选)为索引开始位置
迭代方法:
every() 对数组中的每一元素运行给定的函数,如果该函数对每一项都返回true,则该函数返回
some() 对数组中的每一运行给定的函数,如果该函数对某一项返回true,则返回true
filter() 对数组中的每一项运行给定的函数,会返回满足该函数的项组成的数组
map() 对数组中的每一元素运行给定的函数,返回每次函数调用的结果组成的数组
forEach() 对数组中的每一元素运行给定的函数,没有返回值,常用来遍历元素