文末
篇幅有限没有列举更多的前端面试题,小编把整理的前端大厂面试题PDF分享出来,一共有269页
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
(3)全局中this指向window对象
(4)对象的方法函数
Var obj = {fn:function(){}}
对象名.方法名() obj.fn(); this->调用方法的对象(对象名)obj
例1.普通函数this默认指向window
function fun(){
console.log(this) //window
}
fun() //相当于window.fun()
例2.对象的方法 对象.方法调用this指向该对象
let obj={
name:'胡歌',
age:"18",
speak(){
console.log(this.name+'今年'+this.age,this)
//胡歌今年18 this指向这个对象
}
}
obj.speak() //谁调用这个方法指向谁
例3.函数谁调用指向谁
function constructorFun(name='虹猫蓝兔七侠传',age='16'){
this.name=name;
this.age=age;
this.speak=function(){
console.log(this.name+'的年龄是'+this.age,this)
}
}
let childObj = new constructorFun('胡歌',20)
childObj.speak()
//胡歌的年龄是20 this指向childObj这个对象
//this指向实例
//比如:vue实例 就是new出来的 在使用中通常会使用this点方法名来使用方法,这些方法都是vue这个类上面的方法。
例4.事件对象 谁触发事件指向谁
<div id="box">我是id=box盒子</div>
let boxid = document.getElementById('box')
boxid.onclick=function(){
console.log(this) //指向box这个dom对象
this.innerHTML='我是用this改变后的innerHTML'
}
例5.箭头函数this指向外层作用域的this
<div class="box">我是class=box盒子</div>
let boxclass = document.getElementsByClassName('box')[0]
boxclass.onclick=()=>{
console.log(this) //当前作用域外层this指向window
this.alert('我是window对象')
}
总的来说:
①方法函数:对象.方法() ; this->调用方法的对象
②普通函数:( window.) 函数名() this->window
③事件处理函数: oDiv.οnclick= function(){} oDiv.onclick() this->添加事件的元素
④全局中的this指向window对象
2.作用域、作用域链
它是指对某一变量和函数具有访问权限的代码空间
在js中只有两种作用域
1.全局作用域:script标签内部的区域就是全局作用域
2.局部作用域:函数大括号内部的区域就是局部作用域
在js中只有函数可以划分作用域,因此每个函数的大括号内部都是一个局部作用域
window.onload = function () { //在这里再写上你的函数 }
因此我们称局部作用域为函数作用域
1.全局变量 声明在全局的变量
2.全局作用域就是全局变量起作用的范围
3.局部变量 在函数内部声明的变量
4.局部作用域就是局部变量起作用的范围
<script>
//script标签中的空间就是全局作用域
//全局作用域
//a变量就声明在了全局作用域,就是一个全局变量
var a; //全局变量
a(a)
a = 10;
function a(a) {
//函数大括号内局部作用域
//在函数内部声明的变量就是局部变量
let b = 10;//局部变量
console.log(a)
a = 100
}
console.log(a)
console.log(b) //b is not defined
var c;
console.log(c)//undefined
</script>
作用域链
会先在当前作用域查找变量,当前没有向上一级查询
1.当前有使用当前的变量。
首先,函数不调用不执行,所以调用了fun函数,在fun函数中,有一个函数a,调用了函数a,打印了a,调用a会执行a函数,里面var了一个a赋值为10,所以在函数a中打印a出的结果为10,在fun函数中打印a的结果是函数a这个函数体。
2.当前没有向上一级查找变量,一直到全局作用域为止,如果还是没有会报错,xxx is not defined。
var c = 100;//全局作用域中有c
function num(b) {
//上一级函数局部作用域也没有c
var a = 10;
function sum() {
console.log(a + b + c) //当前函数局部作用域没有c
}
sum()
}
// num(10) //10+10+100
num(10) //120
3.浏览器预解析变量提升
提升的对象包括:
1.函数声明
2.变量声明
3.函数内部作用域默认形参声明
1.函数声明和变量声明是同一个变量名
当函数声明和变量声明冲突的时候,变量声明无法覆盖函数声明,变量赋值可以覆盖函数声明 所以最后结果为10
具体代码:
a(a) //调用函数
a = 10; //变量
var a; //全局变量
//或者 var a = 10; 同上面两句
function a(a) { //函数
}
console.log(a)//10
浏览器对js代码的预解析,这是代码执行之前的操作,也叫变量提升。
函数和定义变量会被提升到当前作用域最顶端,当函数名和定义变量名字一样时,函数名会覆盖变量定义。
预解析完成后的代码:
//上面预解析完成后是
function a(a) {
}
a(a) //调用函数
a = 10; //给变量a重新赋值覆盖函数体
console.log(a)//10
2.函数形参和变量声明是同一个变量名
a(a) //调用函数
a = 10; //变量
b=20;//变量
var a; //全局变量
function a(a) { //函数
var a = 100;
b=200
console.log(a,b) //100 200
}
var b;
console.log(a)//10
当函数调用的时候,就要进入函数的局部作用域 浏览器还要重新再局部作用域中进行预解析,变量名定义提前 赋值不会提前。
1.参数的传递和函数中变量名冲突,函数形参的值会覆盖预解析的效果
2.在函数执行之前进行预解析,这时候参数还没传递
3.预解析以后 函数内代码开始执行 传参
4.在函数中如果没有定义这个变量 就要在全局作用域中查找
5.赋值的时候函数中没有这个变量根据作用域链也会将全局这个变量的值发生改变
函数体内正常预解析代码,没有形参参与:
var b;
function a(a) { //函数
var a;
a = 100;
b = 200
console.log(a, b)
}
a(a) //调用函数
a = 10; //变量
b = 20;//变量
console.log(a)//10
函数开始执行,形参接受到实参的时候:
var b;
function a(a) { //函数
var a =a; //定义a为形参a 参数
a = 100; //被重新赋值
b = 200
console.log(a, b) //100 200
}
a(a) //调用函数
a = 10; //变量
b = 20;//变量
console.log(a)//10
console,log(b)//20
在执行函数的时候,函数内部有用到b,并且被重新赋值,b由undefined变成200,改变全局变量的值,在后面的同步代码中b又被重新赋值,所以最终打印b的值为20。
数组的引用地址
下面的代码在浏览器运行
var arr = [3, 4];
console.log(arr);
arr.push(5);
console.log(arr);
运行结果为:
点开看到第二行打印,里面还有5
实际第二行代码打印的就是[3,4],但是由于数组是引用数据类型(复杂数据类型),内存地址是一样的,显示的是原来的结果。但包含修改后的结果.(浅拷贝,拷贝栈里面的指针)
第一次打印的时候,内存地址还没有变,第二次打印的时候已经发生了变化,点开第一次打印,所指向的内存地址已经发生了变化,进而数组项数据也发生了变化。
ie: 11 跟不上进度
var arr = [3, 4];
let brr=arr;
brr.push(5)
console.log(arr); 3 4 5
总结:
-
函数式编程其实是一种编程思想,它追求更细的粒度,将应用拆分成一组组极小的单元函数,组合调用操作数据流;
-
它提倡着 纯函数 / 函数复合 / 数据不可变, 谨慎对待函数内的 状态共享 / 依赖外部 / 副作用;
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
Tips:
其实我们很难也不需要在面试过程中去完美地阐述出整套思想,这里也只是浅尝辄止,一些个人理解而已。博主也是初级小菜鸟,停留在表面而已,只求对大家能有所帮助,轻喷🤣;
我个人觉得: 这些编程范式之间,其实并不矛盾,各有各的 优劣势。
理解和学习它们的理念与优势,合理地 设计融合,将优秀的软件编程思想用于提升我们应用;
所有设计思想,最终的目标一定是使我们的应用更加 解耦颗粒化、易拓展、易测试、高复用,开发更为高效和安全;