前端基础1-1 :this指针、闭包、作用域

文章详细介绍了JavaScript中的作用域概念,包括全局作用域、函数作用域和ES6的块级作用域,以及作用域链的工作原理。同时,讨论了this的上下文动态性,展示了不同调用方式下this的指向。此外,还涉及到了call、apply、bind的区别和闭包的应用,包括函数作为返回值、参数和嵌套情况。
摘要由CSDN通过智能技术生成

作用域

含义:定义变量和访问变量的范围

  • 全局作用域:全局作用域是在代码的顶层声明的变量和函数可被访问的范围。在任何地方都可以访问全局作用域中声明的变量和函数,包括其他作用域内部。全局作用域中声明的变量称为全局变量。
  • 函数作用域:函数作用域是指在函数内部声明的变量的可访问范围。这意味着在函数外部无法直接访问在函数内部声明的变量。函数作用域允许在函数内部创建私有变量,这些变量只能在函数内部访问。
  • 块级作用域:块级作用域是在代码块(例如 if 语句、for 循环或 {} 中的代码)内声明的变量的可访问范围。在 ES6(ECMAScript 2015)之前,JavaScript 中没有明确的块级作用域。但是,可以使用 var 关键字在函数内部创建具有函数作用域的变量。ES6 引入了 let 和 const 关键字,它们允许在块级作用域内声明变量,并限制变量的作用范围在当前代码块内。

作用域规定了标识符(变量、函数名等)在程序中的可见性和生命周期。当在代码中引用一个变量时,JavaScript 引擎会根据作用域去找到对应的变量。如果在当前作用域中找不到该变量,则会继续向上级作用域查找,直到找到或者达到全局作用域。这个过程被称为作用域链(Scope Chain)。

作用域链

含义:作用域链指的是变量和函数的可访问性和查找规则。

function outer() {
  const outerVar = 'Outer variable';

  function inner() {
    const innerVar = 'Inner variable';
    console.log(innerVar); // Inner variable
    console.log(outerVar); // Outer variable
    console.log(globalVar); // Global variable
  }

  inner();
}

const globalVar = 'Global variable';
outer();

this的上下文

this是在执行时动态读取上下文决定的,而不是创建时决定

函数直接调用–this指向window

function foo() {
        console.log('函数内部', this) //window
    }

foo()

隐式绑定–this指向调用堆栈的上一级=>对象、数组等引用关系逻辑

function fn() {
	console.log('隐式绑定', this.a) //this指向obj
}
const obj = {
	a: 1,
	fn 
}

obj.fn = fn;
obj.fn();
面试题
const foo={
	bar:10,
	fn:function(){
		console.log(this.bar)
		console.log(this)
	}
}
//取出
const fn1 = foo.fn
//单独执行
fn1()

//结果:因为是单独取出,只是将function这个函数赋值给fn1,所以拿到的this上下文指向的是window,而不是foo这个对象
//undefined
//window
const o1 = {
	txt:'o1',
	fn:function(){
		//直接使用上下文--传统派活
		console.log('o1fn',this)
		return this.txt
	}
}
const o2 = {
	txt:'o2',
	fn:function(){
		//呼叫领导执行--部门协作
		return o1.fn()
	}
}
const o3 = {
	txt:'o3',
	fn:function(){
		// 直接内部构造 —— 公共人
		let fn = o1.fn
		return fn()
	}
}
console.log('o1fn', o1.fn());  //this指向o1
console.log('o2fn', o2.fn()); // this指向o1
console.log('o3fn', o3.fn()); // this指向window


//追问:现在需要将console.log('o2fn', o2.fn())的结果是o2
//1.人为干涉:改变this指向(bind/call/apply)
o2.fn.call(o2)
//2.不人为干涉
const o1 = {
	txt:'o1',
	fn:function(){
		// 直接使用上下文 - 传统派活
        console.log('o1fn', this);
		return this.txt
	}
}
const o2 = {
	txt:'o2',
	fn: o1.fn
}
console.log('o2',o2.fn()) //this指向o2
//先打印 o1fn {txt:'o2',fn:f}
//后打印 o2 o2

显示绑定

function foo() {
    console.log('函数内部', this);
}

foo();

// 使用
foo.call({
    a: 1
});
foo.apply({
    a: 1
});

const bindFoo = foo.bind({
    a: 1
});
bindFoo();
面试题:call、apply、bind区别
  • call vs apply 传参不同 依次传入/数组传入
  • bind返回不同(即返回函数,需要手动执行)
bind的原理 / 手写bind
  • 说明原理,写下注释
  • 补全代码
//1.手写bind => bind挂在位置 => Function.prototype

Function.prototype.newBind = function(){
	//2.bind是什么? 改变this
	const _this = this
    // 接受参数args,第一项参数是新的this,第二项到最后一项是函数传参
    const args = Array.prototype.slice.call(arguments)
    const newThis = args.shift()
	//3.返回值
	return function(){
		return _this.newApply(newThis,args)
	}
}
Function.prototype.newApply = function(context){
	context = context || window
	//挂载执行函数
	context.fn = this
	const result = argument[1] ? context.fn(...argument[1]) : context.fn()
	delete context.fn
	return result
}

闭包

含义:一个函数与它周围状态的引用捆绑在一起的组合
形态

  1. 函数作为返回值
  2. 函数作为参数
  3. 函数嵌套
//函数作为返回值
function mail(){
	const content = '信'
	return function(){
		console.log(content)
	}
}
const envelop = mail()
envelop()

//函数作为参数
let content
function envelop(fn){
	content = 1
	fn()
}
function mail(){
	console.log(content)
}
envelop(mail)

//函数嵌套
let counter = 0
function outFn(){
	function innerFn(){
		counter++
		console.log(counter)
	}
	return innerFn
}
outFn()()

//立即执行函数
let count = 0
(function immediate(args){
	if(count === 0){
		let count = 1
		console.log(count)
	}
})(args)

//实现私有变量
function createStack(){
	return {
		items:[],
		push(item){
			this.items.push(item)
		}
	}
}

function createStack(){
	const items = []
	return {
		push(item){
			items.push(item)
		}
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值