随手笔记【三】

作用域链

  • 作用域就是变量(变量作用域也叫上下文)和函数生效(能被访问)的区域集合
  • 作用域包括全局作用域、函数作用域、块级作用域(ES6提出的let和const)
  • 词法作用域是js遵循的,又叫静态作用域,变量被创建时就确定好了,而非执行阶段确定的
  • 作用域链就是会现在本层作用域查找,查找不到再一层层往上查

对象的原型和原型链

每一个对象都拥有一个原型对象

属性和方法定义在Object对象的构造器函数的prototype属性上,而非实例对象本身

function doSomething(){}
console.log( doSomething.prototype );
// 输出------也就是原型对象
{
    constructor: ƒ doSomething(),
    __proto__: {
        constructor: ƒ Object(),
        hasOwnProperty: ƒ hasOwnProperty(),
        isPrototypeOf: ƒ isPrototypeOf(),
        propertyIsEnumerable: ƒ propertyIsEnumerable(),
        toLocaleString: ƒ toLocaleString(),
        toString: ƒ toString(),
        valueOf: ƒ valueOf()
    }
}

当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾

__proto__作为不同对象之间的桥梁,用来指向创建它的构造函数的原型对象的

person._proto_ === Person.prototype //每个对象的_proto_都是指向它的构造函数的原型对象prototype的
Person.prototype.constructor === Person
Person.prototype._proto_ === Object.prototype //原型对象本身是一个普通对象,而普通对象的构造函数都是Object
Object.prototype.constructor === Object
Object._proto_ === Function.prototype //所有的构造器都是函数对象,函数对象都是 Function构造产生的
Person._proto_ === Function.prototype //构造函数是一个函数对象,是通过 Function构造器产生的
Function.prototype.constructor === Function
Function._proto_ === Function.prototype
Function.prototype._proto_ === Object.prototype
Object.prototype._proto_ === null

this的指向

this 关键字是函数运行时自动生成的一个内部对象,只能在函数内部使用,总指向调用它的对象

this的绑定规则
  • 默认绑定

    严格模式下,不能将全局对象用于默认绑定,this会绑定到undefined,只有函数运行在非严格模式下,默认绑定才能绑定到全局对象

  • 隐式绑定

    函数还可以作为某个对象的方法调用,这时this就指这个上级对象

    var o = {
        a:10,
        b:{
            fn:function(){
                console.log(this.a); //undefined
            }
        }
    }
    o.b.fn();
    

    特殊情况

    var o = {
        a:10,
        b:{
            a:12,
            fn:function(){
                console.log(this.a); //undefined
                console.log(this); //window
            }
        }
    }
    var j = o.b.fn;
    j();
    

    此时this指向的是windowthis永远指向的是最后调用它的对象,虽然fn是对象b的方法,但是fn赋值给j时候并没有执行,所以最终指向window

  • new绑定

    通过构建函数new关键字生成一个实例对象,此时this指向这个实例对象

    特殊情况

    • new过程遇到return一个对象,此时this指向为返回的对象

    • 如果返回一个简单类型的时候,则this指向实例对象

    • 注意的是null虽然也是对象,但是此时new仍然指向实例对象

  • 显示修改

    • apply()、call()、bind()是函数的一个方法,作用是改变函数的调用对象。它的第一个参数就表示改变后的调用这个函数的对象。因此,这时this指的就是这第一个参数

    • new绑定优先级 > 显示绑定优先级 > 隐式绑定优先级 > 默认绑定优先级

箭头函数

在 ES6 的语法中还提供了箭头函语法,在代码书写时就能确定 this 的指向(编译时绑定)

不适用箭头函数的场景

场景1:对象方法
场景2:对象原型
场景3:构造函数
场景4:动态上下文的回调函数
场景5:vue的生命周期和method

执行上下文和执行栈

  • 全局执行上下文:只有一个,浏览器中的全局对象就是 window对象,this 指向这个全局对象
  • 函数执行上下文:存在无数个,只有在函数被调用的时候才会被创建,每次调用函数都会创建一个新的执行上下文
  • Eval 函数执行上下文: 指的是运行在 eval 函数中的代码,很少用而且不建议使用
执行上下文的生命周期包括三个阶段:创建阶段 → 执行阶段 → 回收阶段
  • 创建阶段即当函数被调用,但未执行任何其内部代码之前

  • 创建阶段做了三件事:

    • 确定 this 的值,也被称为 This Binding
    • LexicalEnvironment(词法环境) 组件被创建------------(一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包。每当创建一个函数,闭包就会在函数创建的同时被创建出来,作为函数内部与外部连接起来的一座桥梁)
    • VariableEnvironment(变量环境) 组件被创建--------------在 ES6 中,词法环境和变量环境的区别在于前者用于存储函数声明和变量( letconst )绑定,而后者仅用于存储变量( var )绑定
  • var声明的变量从在创建阶段被赋值为undefined。这是因为,创建阶段,会在代码中扫描变量和函数声明,然后将函数声明存储在环境中,但变量会被初始化为undefined(var声明的情况下)和保持uninitialized(未初始化状态)(使用letconst声明的情况下)。这就是变量提升的实际原因

  • 回收阶段 执行上下文出栈等待虚拟机回收

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值