记录一下前端学习笔记,每天打卡!!
目标:
必知必会: js | 布局样式 | 客户端 | 技术栈
加分项:工具(CI/CD等) 热门模块工程化
进阶:模式 实战/算法
实战项目统一模板:做完的项目都需要自己再思考下下面的模板
业务层:modules network adapter
工程化层 :webpack plugins output
基础:ci/cs util/e2e vue/react monitor
开始第一天知识学习
变量提升&作用域链
- 变量提升
var和function都存在变量提升
相同点:都是提升声明,未执行
不同点:函数提升的优先级更高,且不会被变量声明覆盖,但是值可以被变量赋值后覆盖
题目:
let a = 'global'
function course() {
let b = 'zhaowa'
session()
function session() {
let c = 'session'
teacher()
function teacher() {
// let d = 'yy'
console.log('ds', d)
var d = 'yy' // 变量提升 & 变量提升范围:当前作用域
console.log('d', d); // 作用域生效
console.log('b', b); // 作用域向上查找
}
}
}
course()
// ***********************************
// 提升优先级的问题 => 函数会需要变量
// 变量 函数同时提升时
// 提升维度:变量优先
// 执行维度:函数先打印出来
function test() {}
// ***********************************
// 结论:函数天然的隔离方案 => 模块化
if (true) {
let e = 111
var f = 222
}
console.log(e, f)
补充:
- 块级作用域:非函数区域都称为块级作用域
- var可以忽略块级作用域,let对所有作用域都起作用
总结:
- 对于作用域链,可以直接通过创建态来定位
- 手动取消全局作用域,使用块级作用域+let/const(可以利用块级作用域区做性能优化)
- this指针&上下文
- 函数直接调用 - this指向是window
function foo() {
console.log('函数内部this', this)
}
foo()
- 隐式绑定-this指向的是最后的调用的对象!如果没有找到直接的调用对象,this指向的是全局window
function fn() {
console.log('隐式绑定', this.a)
}
const obj = {
a: 1,
fn
}
obj.fn = fn
obj.fn()
如何改变this指向:
- 使用apply bind call来修改this指针
- 直接将函数赋值为需要指定this对象的函数
补充:
- call和apply区别:传参不同,call是依次传入,apply是数组传入
- bind和call,apply区别:bind返回的是一个新的函数,call和apply是调用后立即执行函数
手写题
解题思路:1.说明原理-写注释。 2.根据注释-补齐代码
- 手写bind
// 1. 需求手写bind=>bind存放位置(挂载)=>Function.prototype
Function.prototype.newBind = function () {
// 2. bind是什么?=>改变上下文=>传入参数:newThis + args1~argsn
const _this = this;
const args = Array.prototype.slice.call(arguments);
const newThis = args.shift();
// 3. bind要什么?=>返回可以执行函数=>上下文被改变了的原函数(原函数参数不变)
return function () {
return _this.newApply(newThis, args);
};
};
Function.prototype.newApply = function (context) {
context = context || window;
context.fn = this;
let result = arguments[1] ? context.fn(...arguments[1]) : context.fn();
delete context.fn;
return result;
};
// *********测试1**********
const ob1 = {
a: 1,
fn() {
console.log(this.a);
},
};
const ob2 = {
a: 2,
fn() {
console.log(this.a);
},
};
ob1.fn.newBind(ob2)();
上面说了上下文作用域的问题,但是我们如何突破作用域呢?闭包!
闭包
什么是闭包?
闭包是只有权访问另一个函数作用域的变量的函数。 举个例子:
function mail() {
let content = 'xin'
return function() {
console.log(content)
return content
}
}
const envelop = mail()
envelop()
总结:函数外部可以通过闭包的形式突破作用域的限制,来获取内部局部变量。所以闭包是模块通信的桥梁,是js模块化的雏形。