zoukankan      html  css  js  c++  java
  • js的作用域链,原型链,以及闭包函数理解

    代码一:

    this.number = 10
    function a() {
      this.number = 20
    }
    a.prototype.init = () => console.log(this.number)
    
    const test = new a() // 构造函数生成一个独立新对象
    test.init() // 10

    解析:之所以输出10,可以把 arrow function(箭头函数) 里的 this 和 arguments 关键字理解为函数作用域里的变量(因为自身没有),他访问变量沿着作用域链向上找而不是直接访问对象属性走原型链,代码中的init上头的作用域就是window,所以他的this指向window.

    注:可以试试把上例代码中的箭头函数换成普通匿名函数(输出就是直接走原型链访问对象属性,number = 20)

    代码二:

    this.number = 10
    function a(){ //闭包函数
       return {
         show: () => console.log(this.number) 
       }  
    }    
    a().show() // 10 函数a的this的指向window
    a.call({number: 20}).show() // 20 call改变了函数a的this指向,箭头函数的作用域指向改变后的函数作用域
    a.call({number: 30}).show() // 30

    解析:闭包函数里return出的箭头函数被调用的时候会一直引用外层函数的变量this或者arguments,所以外层函数this指向被改变,return出的箭头函数里的this也改变了.

    this的指向可理解为两大类:

    1:test();==test.call(window,参数);//直接调用函数,this指向window

    2:obj.test(); == obj.test.call(obj,参数);//函数作为对象的方法被调用,this指向该对象

    注:this指向是在被调用时分配的

    代码三:

    function a() {
     this.say = function() {
     console.log(1)
    }
    }
    a.prototype.say = function() {
    console.log(2)
    }
    var test = new a()
    test.say() // 1

    只有函数有prototype,对象对应_proto_,prototype可以对主函数进行扩充,但不会覆盖主函数内的方法(如果主函数里没有此对象属性就在原型链里查找)。

    简单一句话~js中访问变量沿着作用域链向上走(this),直接访问对象上的属性沿着原型链往下走~(都是就近查找哦)

    对call和apply做补充:

    相同点:都是为了改变对象this指向,参数二不同:call是传进单个参数,apply是数组形式

    apply可以接受一个数组或者类数组对象,console.log(...arguments) === console.log.apply(this,arguments)

     

  • 相关阅读:
    Ubuntu解压缩命令
    小语种优化策略
    外贸seo常用Zen Cart数据库mysql批量执行命令
    ASP Request.ServerVariables
    centos linux 下 crontab e 命令插入及保存
    AJAX 传值给后台
    partial class
    Jquery 实现弹出层
    abstract class
    SQL锁表
  • 原文地址:https://www.cnblogs.com/xiaoxiao666/p/8350617.html
Copyright © 2011-2022 走看看