this指向解析

164 阅读3分钟

一.小记

网景:javascript

IE:jscript

ECMA 以 javascript 作为核心,定义了其规范 ECMAScript-262

ES3 ES5(在ES3的基础上,新增一些API,新增的API是不兼容IE8及以下浏览器)

2015年:ES6 「新语法规范:let/const/解构赋值/...运算符/箭头函数/模板字符串/Promise/Set/Map/....」 每年6月份我们都升级一次 版本号重定为: ES2015 ES6 ES2016 ES7 .... ES2021 ES12

navugator:浏览器对象

  • userAgent:获取;浏览器的详细版本信息

ECMAScript:JS的规范

二、JS的数据类型

  • 原始值类型(俗称:基本数据类型)
    • number
    • string
    • boolean
    • null
    • undefined
    • symbol
    • bigint
  • 对象类型(俗称:引用数据类型)
    • 标准普通对象(纯粹对象)例如:{} 对象.proto===Object.prototype
    • 标准特殊对象 例如:数组,正则,日期,错误。。。
    • 非标准特殊对象 例如:1是原始值中的数字类型;new Number(1)是Number类的实例,他是对象类型,而且是非标准特殊对象;所以原始值对应的对象类型实例都是非标准特殊对象;
    • 可调用执行函数(内部实现call),也叫做“函数对象”

三、JS中的执行上下文「EC」

1、定义:

供代码执行的环境,进栈执行,执行完可能释放也可能不释放

  • 全局执行上下文 EC(G)
  • 块级私有上下文:除函数/对象之外的大括号中,但凡出现基于let/const/function声明变量的,都会产生块级上下文
  • 函数私有上下文:函数执行产生的

2、THIS:

执行主体,谁把它执行的「THIS是谁,和函数在哪创建以及在哪执行都没有半毛钱的关系」

  • 全局执行上下文中的THIS是:window
  • 块级私有上下文中的THIS是:它没有THIS,用到的THIS都是所处环境中的THIS
  • 我们都是研究函数私有上下文中的THIS是谁

3、JS函数中,THIS可能出现的五种情况:

  1. 给当前元素的某个事件行为绑定方法,当事件行为触发,绑定的方法会执行,此时函数中的THIS是当前操作元素本身!

    box.onclick=function(){ //点击box后:this->box };

  2. 方法执行,看方法名前面是否有“点”;有“点”,“点”前面是谁THIS就是谁;没有“点”,THIS是window/undefined; // Array.prototype.slice 想把这个slice方法执行? let arr=[]; arr.slice(); //arr基于原型链机制,找到数组原型上的slice方法执行 slice中的this->arr arr.proto.slice(); //slice中的this->arr.proto / Array.prototype Array.prototype.slice(); //slice中的this->Array.prototype const slice=Array.prototype.slice; slice(); //slice中的this->window/undefined ---- const slice=Array.prototype.slice; let arr=[10,20,30,40]; arr.slice(2); //->[30,40] 找到slice把其执行,方法中的this是arr,所以查找的是arr中索引2及后内容 slice.call(arr,2); //->[30,40] ---- arguments函数的实参集合「类数组,不是Array的实例」 arguments.slice(0); //报错:arguments.slice is not a function slice.call(arguments,0); //这样就好了:把数组原型上的slice执行,让其this变为arguments,实现类数组借用数组的方法,以此达到类数组转换为数组的效果 ----

  3. 匿名函数中THIS的分析 3.1. 自执行函数 (function(){ //this:window/undefined })();

 3.2. 回调函数:一般this都是window,除非特殊处理了
    const func=function(callback){
        callback();
    };
    func(function(){
        //this:window/undefined
    });
    ---
    const func=function(callback){
        callback.call(obj); //特殊处理
    };
    func(function(){
        //this:obj
    });
    ---
    let arr=[10,20,30];
    arr.forEach(function(item,index){
        执行数组原型上的forEach: this->arr  callback->传递的回调函数  迭代数组中的每一项,每迭代一次就把回调函数执行一次
        item:当前迭代这一项
        index:当前迭代这一项的索引
        回调函数中的this->window
    });
    arr.forEach(function(item,index){
        //this->obj
    },obj); forEach中传递的第二个参数,就是改变回调函数中this指向的