您的位置:首页 > 职场人生

JS 面试知识学习历程(第三天) -- 作用域和闭包

2018-01-31 11:34 495 查看

Chapter3 JS基础知识(中)—作用域和闭包

这是我自己的学习过程总结,如果有什么写的不清楚的地方,欢迎大家交流、批评、提问。可以在这里评论,也可以在github上提问,谢谢大家

题目

说一下对变量提升的理解

说明this几种不同的使用场景

创建10个< a >标签,点击的时候弹出来对应的序号

如何理解作用域

实际开发中闭包的应用

知识点

执行上下文

this

作用域

作用域链

闭包

执行上下文

console.log(a)  //undefined
var a = 100

fn('zhangsan')  // 'zhangsan' 20
function fn(name) {
age = 20
console.log(name, age)
var age
}


在一段script或者一个函数中,在第一行之前都会先生成一个执行上下文

范围:一段< script >或者一个函数

全局:变量定义、函数声明

函数:变量定义、函数声明、this、arguments

注意: 提前的是函数声明,函数表达式只会当作变量定义提前

fn()  //不会报错
function fn () {
//函数声明
}

//相当于 提前了 var fn1 = undefined
fn1()  // 会报错
var fn1 = function () {
// 函数表达式
}


this

this要在执行时才会确定值,定义时无法确认

var a = {
name: 'A',
fn: function () {
console.log(this.name)
}
}
a.fn()  // this === a
a.fn.call({name: 'B'})  // this === {name: 'B'}
var fn1 = a.fn
fn1()  // this === window


作为构造函数执行

function Foo(name) {
this = {}
this.name = name
return t
c5f8
his
}
var f = new Foo('zhangsan')


作为对象属性执行

var obj = {
name : 'A',
printName: function () {
console.log(this.name)
}
}
obj.printName()  // 'A'


作为普通函数执行

function fn() {
console.log(this)  //this === window
}
fn()


call apply bind

// 不知道call、apply、bind语法的,先去看看语法
function fn1(name) {
alert(name)
console.log(this)
}
fn1.call({x:100}, 'zhangsan')
// apply和bind差不多
var fn2 = function (name,age) {
alert(name)
console.log(this)
}.bind({y:200})
fn2('zhangsan',20)


作用域

没有块级作用域

if(true) {
var name = 'zhangsan'
}
console.log(name) // 'zhangsan'


只有函数和全局作用域

var a = 100
function fn() {
var a = 200
console.log('fn', a)
}
console.log('global', a) // 100
fn() //200


作用域链

var a = 100
function fn() {
var b = 200

// 当前作用域没有定义的变量,即“自由变量”
// 去定义!!的时候父级作用域寻找a
console.log(a)  //100

console.log(b) //200
}
fn()


var a = 100
function F1() {
var b = 200
function F2() {
var c = 300
console.log(a)
console.log(b)
console.log(c)
}
F2()
}
F1()  //100 200 300


闭包

function F1() {
var a = 100

// 返回一个函数(函数作为返回值)
return function() {
console.log(a)  //自由变量,父作用域寻找
}
}
// f1 得到一个函数
var f1 = F1()
var a = 200
f1()  // 100


闭包的使用场景

函数作为返回值(上一个demo)

函数作为参数传递

function F1() {
var a = 100
return function () {
console.log(a)
}
}
var f1 = F1()

function F2(fn) {
var a = 200
fn()
}
F2(f1)  //100


解题

说一下对变量提升的理解

主要就是对执行上下文的理解

变量定义

函数声明(注意和函数表达式的区别)

说明this几种不同的使用场景

作为构造函数执行

作为对象属性执行

作为普通函数执行

call apply bind

创建10个< a >标签,点击的时候弹出来对应的序号

// 官方写法  我自己的写法在github中的chapter1中的chapter1-04.html
var i
for (i = 0; i < 10; i++) {
(function (i) {
var a = document.createElement('a')
a.innerHTML = i +'<br>'
a.addEventListener('click', function (e) {
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
})(i)
}


如何理解作用域

自由变量

作用域链,即自由变量的查找

闭包的两个场景

实际开发中闭包的应用

// 闭包实际应用中主要用于封装变量,收敛权限
function isFirstLoad() {
var _list = []
return function (id) {
id(_list.indexOf(id) >= 0) {
return false
} else {
_list.push(id)
return true
}
}
}
// 使用
var firstLoad = isFirstLoad()
firstLoad(10) //true
firstLoad(10) //false
firstLoad(20) //true


gitbub地址 持续更新 可下载

https://github.com/zust-hh/JavaScript_interviewing_knowledge_learning
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: