前端面试题--day01

1.作用域

一般理解指一个变量的作用范围,另外注意js中没有块级作用域

1.1全局作用域

  1. 全局作用域在页面打开时被创建,页面关闭时被销毁

  2. 编写在script标签中的变量和函数为全局作用域,页面任何位置都能访问

  3. 全局作用域中声明的变量和函数会作为window对象的属性和方法保存

  4. 例:书写以下代码,在浏览器控制台中查看window对象,全局变量的值均可在window对象中找到

    <body>
        <script>
            var b = 12
            var bb = {
                a: 1990
            }
        </script>
    </body>

1.2函数作用域

1.调用函数时,函数作用域被创建,函数执行完,作用域销毁

2.每次调用函数都会创建一个新的函数作用域,相互之间是独立的

3.在函数作用域中可以访问全局作用域的变量,函数外部不能访问函数作用域内的变量

4.在函数作用域中访问变量与函数时,会先从自身作用域中寻找,若没找到,再从函数上一级作用域中寻找,直到全局作用域

1.3作用域的深层次理解

1.3.1执行期的上下文

  1. 当函数代码执行的前期会创建一个执行期上下 文的内部对象AO

  2. 这个内部的对象是预编译时创建出来的,因为当出次数调用时会先进行预编译

  3. 在全局代码执行的前期会创建一个执行期的上下文对象GO

1.3.2函数作用域编译

  1. 创建ao对象 AO{}

  2. 找形参与变量声明,将形参与形参名当做AO对象的属性名值为UNDEFINED

  3. 实参形参相统一

  4. 在函数体里面找函数声明,值赋予函数体

1.3.3预编译的时候做了哪些事情

例子:

function fn (a, c) {
    console.log(a)//function a(){}
    var a = 123 
    console.log(a)//123
    console.log(c)//function c(){}
    function a () { }
    if (false) {
        var d = 678
    }
    console.log(d)//undefined
    console.log(b)//undefined
    var b = function () { }//表达式
    console.log(b)//function(){}
    function c () { }
    console.log(c)//function c(){}
}
fn(1, 2)
  • 创建ao对象

    //全称:active Object活动对象,保存函数调用时的局部变量,其实AO对象就是函数作用域对象
    AO:{}
  • 找形参和变量声明,作为ao对象的属性名 值是undefined

    AO:{
    a:undefined 
    c:undefined
    d:undefined
    b:undefined
    }
  • 实参和形参相统一

    AO:{
    a:undefined -->1
    c:undefined -->2
    d:undefined 
    b:undefined
    }
  • 找函数声明(不是表达式如:a=function(){}),会覆盖变量的声明

AO:{
a:undefined -->1 -->function a(){}
c:undefined -->2 -->function c(){}
d:undefined 
b:undefined
}
  • 整个程序实际运行如下
function fn (a, c) {
    //第一步找形参和变量声明,作为ao对象的属性名 值是undefined
    var a;//undefined
    var d;//undefined
    var b;//undefined
    var c;//undefined
    //第二步实参和形参相统一
    a = 1
    c = 2
    //第三步找函数声明,会覆盖变量的声明
    a = function a () { }
    c = function c () { }
    //接下来就按原代码顺序执行
    console.log(a)//function a(){}
    a = 123
    console.log(a)//123
    console.log(c)//function c(){}
    function a () { }
    if (false) {
        d = 678
    }
    console.log(d)//undefined
    console.log(b)//undefined
    b = function () { }//表达式
    console.log(b)//function(){}
    function c () { }
    console.log(c)//function c(){}
}
fn(1, 2)

1.3.3全局作用域的预编译

  • 创建GO对象

  • 找变量声明,将变量名作为GO对象的属性名值为undefined

  • 找函数声明,值赋予函数体

2.this指向

  • 全局作用域或者普通函数中this指向全局对象window。定时器里的this指向window

  • 对象中的方法谁调用this指向谁

  • 构造函数中this指向构造函数实例

var name = 222
var a = {
    name: 111,
    say: function () {
        console.log(this.name)
    }
}
var fun = a.say
fun()//fun.call(window)===222
a.say()//a.say.call(a)===111
var b = {
    name: 333,
    say: function (fun) {
        fun()
    }
}
b.say(a.say)//在b.say中调用a.say方法,此时fun()的调用者为window相当于fun.call(window)===222
b.say = a.say//b.say为function(){console.log(this.name)}
b.say()//因为b.say的值已改变所以this指向为b相当于b.say.call(b)===333

2.1箭头函数中的this

  • 箭头函数不绑定this关键字,箭头函数中的this指向的是函数定义位置的父执行上下文this,箭头函数内部this值只能通过查找作用域链,同时也不能用作构造函数

  • 例如:箭头函数本身所在的对象为obj,而obj的父执行上下文(作用域)为window因此输出为11(obj作用域于window所以箭头函数this指向于window)

    var x=11
    var obj={
    x:22,
    say:()=>{
    console.log(this.x)}
    }
    obj.say()//值为11
  • 自我理解成:箭头函数的this指向为上一级的上一级的this,例如下例代码:gets的父(上一级)为obj,obj的父(this)为window,所以gets里的this指向为window。而geta中fn的this指向为obj,因为fn的父(上一级)为geta,而geta的父(上一级)为obj因此this指向为obj

    var b = 12
            var obj = {
                b: 1990,
                gets: () => { console.log(this.b) },
                geta: function () {
                    var b = 2000;
                    var fn = () => new Date().getFullYear() - this.b
                    return fn()
                }
            }
            obj.gets()
            console.log(obj.geta())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进阶的菜熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值