定义:指变量访问的范围,离开了这个作用域,变量不能被访问。
分类:局部作用域和全局作用域,局部作用域分为函数作用域和块作用域
函数作用域,在函数内部或者形参都是在函数作用域内,函数内定义的变量只能在函数里访问,函数执行完就被清空
块作用域,以{}包围内定义的变量就是块作用域,for,if括号内定义的变量都是在块作用域上。但是在{}上的var无法在块作用域上,可以有var在函数作用域上。
局部作用域上的变量都只能在作用域上访问。外部无法访问。定义在{}的变量不在块作用域上。
局部作用域内都能访问到全局作用域上。
全局作用域在script标签或者js文件的最外层。
????作用域本质上是底层的变量查找机制。
????????
作用域在内存当中的存在情况,在栈内有函数,函数会有函数作用域的部分,存在于变量环境内,和函数所有代码块都存在于词法环境。全局变量中也有全局变量存在于变量环境,但是变量环境可以被window访问到。词法环境内是全局下的块级作用域,let和const定义的都是块级作用域。
内存上都存在作用域链,访问的时候会往更大的作用域查找,首先查找的是自身所在作用域,如果在词法环境,第二个是变量环境,再去查找的时候,只会找变量环境。作用域链是为了变量查找,且一定是往大的范围查找。查找的时候机制就是如此,不会有机制使得往更小的作用域查找。
简称GC,
内存生命周期:内存分配(系统分配)=>内存使用=>内存回收(由垃圾回收机制自动回收)
垃圾回收机制会自动回收局部变量的内存。
全局变量在关闭页面时被垃圾回收机制回收。
严格来说:无法释放内存
广泛而言:内存生命周期长,无法被回收。
垃圾回收机制会回收变量所在内存,垃圾回收机制也会回收对象,对象的回收计数,看是否还有变量指向。计数。
但是当两个对象互相指向则无法回收该内存。对象也可以通过程序员自己回收。
标记清除法是看对象能否通过程序被找到,来是否回收。
垃圾回收机制会在函数不再用时,回收函数内存。变量回收也是一样。看该变量是否能被存在的变量访问到。
闭包是指有权访问另一个函数作用域中的变量的函数。
定义:函数内还有函数,且内层函数用到了外层函数定义的变量(无论是变量环境还是词法环境)
作用:使得函数外的能访问外层函数定义的变量。用闭包函数的return能返回变量的值,但是只是返回一个字面值,使得外部能得到,当无法访问内存,无法修改。
闭包内层函数还能访问外层函数的变量,此时变量的内存不会回收。
闭包能实现数据私有且能被访问,不能被修改。
将var定义的变量提升到作用域最前面,只提升声明,不提升赋值。变量在一个作用域上,当于
let c=2
let b=1
var?a=1
var a
let c=2
let b=1
a=1
函数提升,在作用域内会将所有函数写到作用域最上层。只提升声明,不调用。函数也只能在作用域上才能访问。
每一个函数(非箭头函数)都有动态参数,可以直接在arguments变量,这个变量是参数形成的伪数组。每个函数内都有都能访问。
arguments该参数最后得到的是Objet类,是对象,不过形式和数组一样,但不是Array数组对象。无法有数组对应的方法。但是Object类内也有length属性。每个函数内的arguments都是调用后执行时,自动将所有形参生成的伪数组。
剩余参数赋值赋得是真数组。...arr变量还是arr,但是形参写了...会知道将前面参数之后的所有实参组成数组赋给...后的变量。剩余参数后不能再写形参,剩余参数只写在形参内。
该运算符和剩余参数写法一样,但是剩余参数是写在形参上,运算符不是,写在其他地方表示,
扩展运算符只能跟数组。作用是相当于写了一个数组元素隔逗号的一行数(去掉【】)。写了这种,可以写到实参上。
箭头函数无函数名,可以用来替代匿名函数。更为简单的语法
匿名函数的写法
function(){
}
箭头函数的写法
(形参)=>{
代码块
}
执行箭头函数,调用箭头函数时,也是将参数传递,然后执行代码块。
箭头函数的简化写法
1.箭头函数基本写法
()=>{
}
2.只有一个参数可以省略括号
a=>{
}
3.代码块内只有return语句时,可以直接写return后面的
(a)=>a
相当于
(a)=>{
return a
}
4.当代码块只有一行代码,但不是return可以去掉{}
(a)=>{
console.log(a)
}
简化
(a)=>console.log(a)
5.当返回值是对象时,由于对象如果写{name:'zhangsan'},程序将认为是代码块的{}。
返回值是对象,且只有返回语句时,对象需要()
(a)=>{
return {name:'zhangsan'}
}
简化(a)=>({name:'zhangsan'})
上诉简化时,程序都知对应什么执行的时候也会对应执行。
箭头函数时用来替代匿名函数,写法更为简便。箭头函数没有动态参数arguments,有剩余参数(...arr)
this是底层的一个参数,函数的隐式形参。this是调用该函数的对象。this内存存的是调用函数的对象。箭头函数没有this变量,当找不到this这个变量会去作用域链上一层找this。
为什么普通函数的调用者是window对象???
函数也是存在于变量内的。且直接写函数,有函数提升。存在于window上。调用时,我们省略了window。
数组解构是我们可以定义变量名为数组格式,内部写变量名。且内部a,b
,c也会在内存中定义一个变量,分别对应。
两个变量互换值,可以
let a=1,b=2;
[b,a]=[a,b]
这种写法把变量名都写到数组内,可以直接定义多个变量等于数组上的值。[]可以不写为变量名,直接使用也可以,作为=号的左边,作为变量,可以分别赋值。在这个符号上面也可也写剩余变量。也可也和形参一样赋一个值。
可以省略变量
const [a,b,,d]=[1,2,3,4]
相当于
const a=1
const b=2
const d=4
写[]的形式可以实现多个变量的赋值。且[]内也可以写[],也是实现变量的赋值。
变量赋值时也可也用{}来同时赋多个值,无论用[]还是{},格式都必须相同,会找数组或对象对应的进行变量赋值。
但是{}变量进行赋值时,需要变量名和对象内所需要的属性名相同,还有一种就是所需属性名:自己定义的变量名,则会赋值给我们定义的变量名。
let a=0
{name:a}={name:'zhangsan'}
console.log(a)//zhangsan
{}和[]是可以一起用的。[]号内一个{}和一个数组元素所占一样。
多重对象解构
const pig={
name:'佩奇',
family:{
mother:'猪妈妈',
father:'猪爸爸'
},
age:6
}
const? {name,family:{mother,father},age}=pig
{}解构时,后面的:也可以是[],或者{}都可以,会给{mother,father}赋值。
我们传参时,也可以将形参写成这种形式,且以{}/[]可以只需要一部分。
写成形参其实也是赋值。赋值就和写的代码一样。就是会有多个变量赋值。不过这些变量都是形参。
以解构为一行代码开头或者立即执行函数,需要在前一句加上;代表语句的结束,否则会认为这两行是一行代码。我们平时换行都是代表语句的结束。
1.forEach()
数组调用该方法时,执行该方法,会使得调用的数组遍历,且遍历时调用该函数。调用该函数就会执行。只要执行代码,比如参数为函数内部写了alert都会执行。
创建对象的方法
1.const a={name:‘张三’,age:18}
2.const a=new Object({name:‘张三’,age:18})
3.const a=new? Pig('张三',18}
functiom Pig(name,age){
this.name=name
this.age=age
}
创建对象可以用内置构造函数,但是形参是{}形式,我们直接写{},是省略了new Object()。该构造函数会创建对象。且在控制台是这种格式.构造函数内有对应的方法。
我们new这个关键词就会创建对象,然后执行对应的函数,this是执行这个对象的。new Object也是构造函数也是创建对象。这些函数可以当成普通函数。对象的创建其实是new+函数。返回值是对象也是new。不是函数来返回。
创建类似的对象,属性名相同属性值不同的对象,可以自己写构造函数,可以更为简单。
被用作构造函数的函数有两个约定;1:大写字母开头,采用大驼峰方法,每一个单词首字母大写
(普及以下小驼峰,首字母不大写,第二个单词开始首字母大写
2.创建对象需要new+构造函数()
对象内存可以直接新增属性的,如果没找到。
实例成员和静态成员是只有对象才存在的,如果不是对象只是简单的基本数据类型,只在变量内存存一个数字,是没有成员的。实例成员只有对象才有,通过对象才能访问的。静态成员是
这种内存不在对象内存上,只能调用函数时访问。构造函数被调用也会创建函数作用域下的。
但是对象只能访问到在对象上的。且所有的构造函数.静态成员有一块内存,存在于哪,可以通过函数来访问。所有的函数可以通过程序内能访问到函数的变量.变量,可以增加该变量。且是静态变量,对象无法访问。
a.age=18
我们所有的写法写基本数据类型的时候,底层都会给数作为参数创建对应的对象。因此这些数据才可以调用属性/函数。
比如1.isFinite()自动将数字都 new Number(1).isFinite().我们这些字面值都是基本数据类型,但是这些构造函数都会创建成对象类型。且这些对象类型在输出台上还是写成基本数据类型。调用方法和变量赋值会new 构造函数。对象类也有叫Numebr的。
静态方法
Object.keys(对象)返回值是对象的所有属性名,按序排成数组。
Object.values(对象) 返回值是对象的所有属性值,按序排成数组。
Object.assign(对象A,对象B),给对象A增加对象B的键值对。不会返回值,直接是对象A内存发生改变。
?
该·构造函数有对应的实例函数。变量名为foreach,filter,map,reduce的方法。
foreach函数是数组调用这个函数,函数内部写的数组遍历,且每一次遍历都调用forEach参数的函数。只是调用,但是不会对数组做出什么变化。this是指向该数组。参数为函数的返回值也不会做什么
filter函数,参数是函数,函数内部是每一个this遍历,遍历的时候调用函数,return上写条件,返回值为true的那一个来组成新数组,返回。
reduce函数,也是一个参数是函数,作用是遍历数组,遍历数组的时候,如果有第二个参数,则第一次调用数组的时候,传的两个参数第一个是第二个参数,第二个是数组的第一个元素,然后得到返回值,遍历调用第二次传的是这个第一次的返回值,第二个参数是数组第二个元素。依次。得到左后一次遍历的值。返回这个值。如果reduce没有第二个参数,则第一次调用传数组第一个和第二个元素。
map函数,参数是函数,遍历这个数组,然后遍历的时候调用这个函数参数。将每一次调用的返回值组成新的数组返回。
join方法,遍历数组,每一次都将数组的元素和参数拼接,最后输出最终的字符串。
find方法,参数是函数,每一次都去遍历数组,调用参数,传的是数组元素,return上是条件,当第一次return true的时候,停止遍历,返回当前的数组元素。
erery方法,参数也是函数,遍历数组,每一次都去调用这个函数,每一次都返回true,最后就返回true,否则返回false
some方法,参数是函数,遍历数组,每一次都去调用,调用return返回的只要有true,最后就是true
length属性,得到字符串内部多少个字符
split方法,将调用的字符串以split的参数分开,返回数组,数组内是字符串。
(数组的join方法,返回字符串)
subString方法,第一个参数是字符串内第几个字符,开始截取,第二个参数是截取到第几个的前一个字符,subString(1,3)截取第1和第2个字符,字符从0开始算。如果没写第二个参数,会截取到最后一个字符,包括最后一个。
statesWith方法,对比调用的和传入的是否相同,且,没传入第二个参数默认是0,从第0个下标开始对比,第二个参数是多少就从第几个下标开始,一个一个字符对比。
includes方法,
字符串的该方法会对比调用的字符串和参数传入的是否有一样的,调用字符串是否包括传入的字符串,第二个参数可以写数字,表示从调用字符串的第多少个字符开始看,第一个字符下标是0.返回值是true/false,空格也是字符,这里对比可以是第二个下标后的任意一个下标相同。
该构造函数,是对象调用方法,参数是几就保留几位小数,没有对应位的小数就补0,有的话,保留的最后一个小数位四舍五入。
返回值是数字。