1.箭头函数没有this
每个函数在定义被ECMAScript解析器解析时,都会创建两个特殊的变量:this和arguments,换句话说,每个函数都有属于自己的this对象;
<script> window.a = ‘windous‘ window.b = ‘bbbbwindous‘ window.name = ‘lisi‘ //1.块级作用域下不会被创建this;this只有全局对象window和常规函数才会创建 { let a = ‘aaaa‘; console.log(this.a); } //2对象下也不会被创建this;都只能去外层寻找 let obj1 = { name:‘lihua‘, nicheng:this.name, } console.log(obj1.nicheng); //打印的windou的namelisi,所以对象也没有this console.log(obj1.name);
//3.自定义常规函数的this,ECMAScript解析器会帮助我们自动创建并指向函数本身 function f1(){ console.log(this);//ECMAScript解析器会帮助我们自动创建,打印是fi(){} this.b = ‘bbbbb‘; //我们可以调用它,做一些赋值 console.log(this.b);//结果是‘bbb’ } let ff = new f1();//当我们初始化实例的时候,this就会指向实例ff console.log(ff.b);//因此我们可以通过实例名.属性名的方式调用this.b,打印是‘bbb’ //4.常规函数作为对象的方法时,ECMAScript解析器会帮助我们自动创建,并指向对象 let obj2 = { name:‘lihua‘, nicheng(){ let name = ‘xiaoming‘; console.log(this);//指向的是obj2 return this.name; } } console.log(obj2.nicheng());//打印lihua
//5.自定义箭头函数时,我们知道箭头函数和无论如何都不会被ECMAScript解析器创建this, //所以虽然也可以用this但是都是调用外层的this,所以这里直接调用window let f2 = () => { console.log(this); //打印window } f2(); //6.箭头函数作为对象方法时,仍然需要调用外层的this, //对象也没有this,所以只能调用对象外面的this,那还是this //注意和常规函数做方法时区别,常规函数是由this,并被编译器指向了对象,而箭头函数是直接就没有this,只能去外面找; let obj3 = { name:‘lihua‘, nicheng:() => { console.log(this);//打印window return this.name } } console.log(obj3.nicheng());//打印lisi </script>
总结:
- 只有window和常规函数会被编译器创建this对象,块级作用域、对象{}、箭头函数都不会,他们只能去外面寻找。
- 常规函数的this在自定义时指向自己或实例,在对象做方法时指向对象;
特性:
- 特性一:this是静态的,this始终指向函数申明时外层作用域下的this值;而非箭头函数this会随着call和apply而改变;
- 特性二:箭头函数不能作为构造函数,去实例化对象;
- 特性三: 不可以使用aruguments变量
- 特性四:箭头函数在符合条件的情况下,还可以简写,更少书写代码;
使用:
-
对于需要使用object.method()方式调用的函数,使用普通函数定义,不要使用箭头函数。对象方法中所使用的this值有确定的含义,指的就是object本身。
-
其他情况下,全部使用箭头函数。
2.var和let const区别
(1)bianliang提升
我们首先通过 var
关键字声明了 name
变量。这意味着变量被提升了(内存空间在创建阶段就被设置好了),直到程序运行到定义变量位置之前默认值都是 undefined
。因为当我们打印 name
变量时还没有执行到定义变量的位置,因此变量的值保持为 undefined
。
通过 let
和 const
关键字声明的变量也会提升,但是和 var
不同,它们不会被初始化。在我们声明(初始化)之前是不能访问它们的。这个行为被称之为暂时性死区。当我们试图在声明之前访问它们时,JavaScript 将会抛出一个 ReferenceError
错误。
总结,var和let、const都会变量提升,但是var会被自动初始化为undefined,但是letconst不会被自动初始化,如果没有被初始化引用会报错;、
(2)自动赋值
如果一个变量定义的时候没有被赋予访问类型,那么自动会被定义为全局变量var
就像这个防抖动函数里的refresh,timer = setTimeout的时候被系统自动初始化了为var,所以如果多次执行refresh函数,有可能会被下一个函数的clearTimeout给清除掉。
这样看全局变量var
https://www.bilibili.com/video/BV15741177Eh?p=175
3、对象
对象是js非常重要的数据类型,所以,重点再讲解一下;
对象属性方法的定义格式
对象的属性和方法,
- 其中属性就是键值对,
- 其中方法就是键函数对,
具体定义格式如下图:
定义对象的属性没什么说的,定义对象的方法我们一般用第一种格式,即myFunc1,这种方式默认会创造一个匿名函数作为键函数对;我们知道,每个函数都有一个name属性,这种方式定义的时候会将键名赋值给name属性;
最正式的定义格式是格式二,即myFunc2,这个函数是具名函数,函数的name属性就是函数名dirName;
最简介的定义格式是格式三;
(2)对象的键
对象的键都是字符串类型,或者symbol类型
(3)操作对象的属性和方法
如何操作对象的属性:
- e.myVar1
- e["myVar1"]
4、==和===
如果是基本数据类型:
- ==值相等即true,类型会被自动转换成一种
- ===值要相等,类型也要相等,否则false
如果是引用数据类型:
- ==判断值是否相等
- ===判断内存地址是否相等;