每个函数在执行时都有自己的this指向

1. 默认绑定规则:

  1. 全局中,this指向window this === window
  2. 函数的独立调用,this默认指向window (不要把独立调用理解成window调用
// 函数在全局中调用,也就是被window调用
function test(){console.log(this === window) // true
}
test() // window.test()

2. 隐式绑定规则(对象调用)

  1. 通过对象的属性来调用方法时,this指向对象(谁调用指向谁)
var a = 0;
var obj = {a: 2,foo: function () {console.log(this) // 1. 指向objfunction test() {console.log(this) // 2. 指向windowconsole.log(test.caller) // 3. foo匿名函数}test() // 2. 函数独立调用// 4. test声明,test调用,就是IIFE; (function () {console.log(this) // window 5. 直接写IIFE})()}
}
obj.foo()
var a = 0
function foo() {console.log(this)
}
var obj = {a: 2,foo: foo
}
obj.foo() // obj 隐式绑定规则
var bar = obj.foo // 隐式丢失:方法被重新赋值
bar() // window 独立调用
  • 参数赋值

预编译的过程中,实参被赋值为形参(值的拷贝过程:浅拷贝)

var a = 0
function foo() {console.log(this)
}
function bar(fn){ // bar是高阶函数fn()fn.bind(obj)() // 指向obj// 父函数有能力决定子函数this的指向
}
var obj = {a: 2,foo: foo
}
bar(obj.foo) // window 独立调用
  • 数组方法等
var arr = [1]
// forEach还有第二个参数,this指向!!,不传默认是this
arr.forEach(function () {console.log(this) // window
})
arr.forEach(() => {console.log(this) // window
})
function test() {console.log(this)
}
// 不够好的方式
arr.forEach(test.bind(arr)) // arr
// 正确的做法
arr.forEach(function () {console.log(this) // arr
}, arr)
// 不要使用箭头函数+第二个参数改变this指向
arr.forEach(() => {console.log(this) // window
}, arr)
// setInterval(() => {//     console.log(this) // window
// }, 1);
  • 例子
var name = '222'
var a = {name: '111',say: function () {console.log(this.name)}
}
var fun = a.say;
fun(); // 222 独立调用
a.say(); // 111 对象调用

FnName.caller并不能用来检测是否是window调用的函数
返回调用指定函数的函数.
如果一个函数f是在全局作用域内被调用的,则f.caller为null,相反,如果一个函数是在另外一个函数作用域内被调用的,则f.caller指向调用它的那个函数.

2.* IIFE内的this指向window(浏览器中/非严格模式)

  • 不考虑node中

3. 显示绑定 call、apply、bind

  • bar.call(obj,1,2,3,4,5)

  • bar.apply(obj,[1,2,3,4,5])

  • bar.bind(obj)(1,2,3,4,5)

  • 当参数为原始值时,会包装,this指向对应的包装类

  • 当参数为null、undefined,this指向window

  • IIFE + 显示绑定(显示绑定优先级 >> IIFE)

var obj = {a: 1
}; (function () {console.log(this) // obj}).call(obj) 

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。

const module = {x: 42,getX: function() {return this.x;}
};const unboundGetX = module.getX;
console.log(unboundGetX());
// The function gets invoked at the global scope
// expected output: undefinedconst boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// expected output: 42

bind返回值和原函数不相等,返回一个新函数

const module = {x: 42,getX
};
function getX(){return this.x;
}const boundGetX = module.getX.bind(module);
console.log(boundGetX)
console.log(boundGetX())
console.log(boundGetX === getX); // false

4. new 绑定(优先级 >> 显示绑定)

function Person() {this.a = 'a'console.log(this) // Person实例 {a: 'a'}return {a: 'hhh'}
}
var p = new Person()
console.log(p) // 普通对象{a: 'hhh'}

6. 闭包中

var a = 'a';
var obj = {a: 2,foo: function () {var c = 'c'console.log(this) // objfunction test() {console.log(this) // 3. windowconsole.log(c) // cconsole.log(a) // a(全局上的)console.log(obj) // 能访问}return test // 1. test是闭包// 当函数执行时,导致函数被定义,并抛出}
}
obj.foo()() // 2. test() 独立调用

ES5-拓展 this指向的总结相关推荐

  1. ES5和ES6中对于继承的实现方法

    在ES5继承的实现非常有趣的,由于没有传统面向对象类的概念,Javascript利用原型链的特性来实现继承,这其中有很多的属性指向和需要注意的地方. 原型链的特点和实现已经在之前的一篇整理说过了,就是 ...

  2. js基础面试题整理(包含ES5,ES6)

    写一下 Javascript 的原始类型 原始类型:number,string,boolean,null,undefined 引用类型:object.里面包含function,Array,Date T ...

  3. JS高级之面试必须知道的几个点

    深圳市人人聚财招前端啦 ~~~ 招前端,招前端,招前端,欢迎扫码加群,砸简历过来: 前言 这段时间突然发现JS原生好多东西都忘记了,但有些东西确实很重要,所以又重新再梳理一次.主要有函数的3种定义方法 ...

  4. ACL 2019 | 机器翻译深层模型

    随着Transformer(Vaswani et al, 2017)及其变种(Shaw et al., 2018; Wu et al., 2019)的提出,宽而浅的模型结构在神经机器翻译模型受到偏好, ...

  5. ARM 汇编语言编程学习笔记(1)

    0.1.Thumb指令集 Thumb指令集是ARM指令集的子集,其性能更低,但是代码密度更高,功耗更低. Thumb指令集分为Thumb-1指令集和Thumb-2指令集,其中Thumb-1指令集是16 ...

  6. javascript的ES6笔记整理

    添加小程序,兑换各种视频教程/数据资源. 1. 常量:不能被重新赋值. //ES5中声明一个常量,并挂载到window下: Object.defineProperty(window,'PI',{val ...

  7. js(JavaScript)高级

    作用域 变量能够被访问的范围 局部作用域 函数作用域 在函数内部声明的变量只能在函数内部被访问,外部无法直接访问 1.函数的参数也是函数内部的局部变量 2.函数执行完毕后,函数内部的变量就被清空了 块 ...

  8. JVM之(执行引擎、字符串常量池、垃圾回收)-总结

    JVM之(执行引擎.性能监控.垃圾回收)-总结 如想了解更多更全面的Java必备内容可以阅读:所有JAVA必备知识点面试题文章目录: JAVA必备知识点面试题 注意: 本篇主要以HotSpot虚拟机为 ...

  9. ES6/02/创建对象,构造函数和原型,原型和原型链,this指向,类,ES5新增的方法,数组方法,回调函数,ES5新增的字符串方法,ES5中新增的对象方法

    创建对象 1,利用new Object()创建对象 var obj1 =new Object(); 2,利用对象字面量创建对象 var obj2={}; 3,利用构造函数创建对象 function S ...

  10. javascript中this指向问题(es5)

    与我们常见的很多语言不同,JavaScript 函数中的 this 指向并不是在函数定义的时候确定的,而是在调用的时候确定的.换句话说,函数的调用方式决定了 this 指向. JavaScript 中 ...

最新文章

  1. 中科大“九章”历史性突破,但实现真正的量子霸权还有多远?
  2. mysqldump定时备份数据库
  3. java计算器程序代码实现加减乘除_Python+tkinter能实现计算器!太神奇了
  4. Android应用程序键盘(Keyboard)消息处理机制分析(8)
  5. 一周一论文(翻译)——[SIGMOD 19] Elasticutor:Rapid Elasticity for Realtime Stateful Stream Processing
  6. android+六边形布局,android – 带六边形触摸区域的六角形按钮
  7. python find()效率_基于python分别采用同步与异步(协程)方式抓取时光网TOP100电影...
  8. ubuntu清理磁盘空间的几个技巧
  9. EasyRecovery2022数据恢复绿色版
  10. Vue 单文件模板中覆盖引入库 CSS 样式
  11. WinCE系统USB功能定制
  12. 德州大学达拉斯分校计算机科学,德克萨斯大学达拉斯分校排名
  13. 已成功与服务器建立连接,但是在登录前的握手期间发生错误
  14. 有一个人愿意参加第一届校园活力健美操这
  15. 什么是法?什么是僧?
  16. 基于Python的OCR图像识别
  17. 滤波器中截止频率的理解
  18. win11快速启动有必要关闭吗?如何关闭?
  19. 父亲儿子女儿放取水果进程/线程间通信程序设计与实现
  20. matlab ppt 赵银娣,中国矿业大学考研研究生导师简介-赵银娣

热门文章

  1. 读取剪贴板英语转换为国际莫斯码
  2. oracle 同义词_【干货7】Oracle知识关键代码摘要
  3. 常用于评价回归模型优劣的统计量包括( )。_第四十一讲 R-判断回归模型性能的指标...
  4. java图书管理系统技术难度_Java图书管理系统练习程序(一)
  5. python中比较重要的几个函数_Python 几个重要的内置函数 python中的内置函数和关键字需要背过吗...
  6. 各Rendering Path技术以及其在Unity中的实现
  7. matlab 计算N天前(后)的日期
  8. [Pytorch]Pytorch的tensor变量类型转换
  9. 在vue中methods互相调用的方法
  10. Laravel日志查看器 -- log-viewer扩展