一、作用域:
是编程语言中,规定变量储存和访问的规则。
js中作用域有三种: 全局作用域、函数作用域、块级作用域(es6新增)。
内层作用域可以访问到外层作用域的变量,以此形成的作用域层级引用关系就是作用域链,如果在全局作用域也没找到一个变量,js引擎会抛出错误。
二、闭包
引用着另一个函数作用域中变量的函数,就叫闭包;通俗理解就像在外太空穿着太空服的宇航员,需要一个生存环境,闭包就是绑定了执行环境的函数。
自由变量访问:访问本作用域外的变量,在函数定义处查找,不是在调用的地方。
关于闭包的经典考题:
(1)将内部函数返回到全局作用域
function create(){let a = 100;return function(){console.log(a)}}let a = 300;let outterCreate = create();outterCreate()
(2)将函数作为参数,传入函数内部执行
function myFoo(){console.log(a)}let a = 100;function foo(fn){let a = 200;fn()}foo(myFoo)
闭包应用场景:
数据缓存,将缓存数据隐藏在函数内部,向外界提供储存和访问数据的方法。
function myCache(){let cache = {};return {set(key, val){data[key] = val},get(key){return data[key]}}}let cacheTool = myCache()
三,this指向
普通函数的this指向是在执行时绑定,箭头函数的this指向取外层作用域的this。
(1)作为普通函数直接调用,函数内部this指向window
(2)作为对象的方法调用,指向该对象
(3)setTimeout的回调函数中,普通函数内部的this指向window,箭头函数定义时绑定外层作用域this。
(4)call、apply和bind,可以直接改变this
(5)class类中,this指向实例对象
(6)dom事件触发函数中,this指向事件dom节点
四、bind函数手写
Function.prototype.myBind = function () {let thisArg = arguments[0],originArg = this,thisArgObj = Object(thisArg),outterParameters =arguments.length > 1 ? [...arguments].slice(1) : [],myBindFuncitonName = symbol("myBind");thisArgObj[myBindFuncitonName] = this;return function () {let innerParameters = [...arguments],allParameters = [...outterParameters, ...innerParameters];return thisArgObj[myBindFuncitonName](allParameters);};};let fn2 = fn1.bind(obj, 1);fn2(2, 3);
