前言


javascript 的 this 指向主要是依赖上下文对象决定,箭头函数例外。

默认绑定


在全局作用域下调用函数,函数的this默认指向window

注意1:严格模式下,默认指向undefined

function test() {
console.log(this.a);
} var a = 1;
test(); // 1 // 严格模式
function test() {
'use strict';
console.log(this.a);
} var a = 1;
test(); // TypeEror 报错

注意2:全局作用域下 var声明的变量会默认绑定到window,而letconst声明的变量不会

let a = 1;
var b = 1; window.a // undefined
window.b // 1

隐式绑定


当函数引用有上下文对象时,this隐式绑定到这个上下文对象中。

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

隐式丢失

function test() {
console.log(this.a);
} var obj = {
a: 1,
test: test
} var a = 2; // 隐式丢失,this 应用默认绑定规则
var bar = obj.test;
bar() // 2

显式绑定

callapplybind等显式改变this指向。

注意:非严格模式下,callapplybind等传入nullundefined会默认转为window

function test() {
console.log(this.a);
} var obj = {
a: 1
} var a = 2; test(); // 2
test.call(obj); // 1
test.apply(obj); // 1 var bTest = test.bind(obj);
bTest(); // 1

注意2:多次使用bindthis只会指向第一次bindthis

function test() {
console.log(this.a);
} var obj1 = { a: 1 }
var obj2 = { a: 2 }
var obj3 = { a: 3 } var bind1 = test.bind(obj1);
bind1(); // 1 var bind2 = bind1.bind(obj2);
bind2(); // 1 var bind3 = bind2.bind(obj3);
bind3(); // 1

内置函数改变this指向

function test() {
console.log(this.a);
} var obj = {
a: 1
} var arr = [1, 2, 3];
arr.forEach(test, obj); // 打印 3 个 1

new 绑定

使用new操作符会产生如下步骤:

  1. 创建一个新的空对象。
  2. 将新对象与构造函数的prototype相连。
  3. 新对象绑定带构造函数的this
  4. 如果构造函数有返回值,且返回值是对象,则返回构造函数的返回值,否则返回新建的对象。
function create() {
let obj = new Object(); let constructor = [].shift.call(arguments); // obj.__proto__ = constructor.prototype;
Object.setPrototypeOf(obj, constructor.prototype); // 改变 this
let res = constructor.apply(obj, arguments); const isObj = Object.prototype.toString.call(res) === '[object Object]';
return isObj ? result : obj;
}

箭头函数


箭头函数比较特殊,它有以下几个特点:

  1. 没有自身的this,在定义时默认绑定父级作用域的this,即采用词法作用域绑定this.

  2. 没有原型 prototype,无法使用 new 操作符,即不能作为构造函数.

  3. 无法使用callapplybind等显式改变其this.

    const test = () => console.log(this);
    let obj = {}; test(); // window
    test.call(obj); // window const foo = test.bind(obj);
    foo(); // window

最新文章

  1. 常见容易遗漏的html标签
  2. spark MySQL jar 包
  3. MBB类似jquery.bxslider插件轮播效果
  4. Python正则表达式总结
  5. runtime的概念,message send如果寻找不到相应的对象,如何进行后续处理
  6. C#开发学习——存储过程
  7. Django:(博客系统)使用使用mysql数据&创建post/category/tag实体,并同步到数据中
  8. bash与ksh数组使用
  9. c/c++ 重载运算符 类型转换运算符
  10. mpdf中文开发使用文档附demo实例
  11. VS2010 修改模板文件,增加默认注释
  12. Java数据解析---SAX
  13. Eclipse 中修改tomcat设置内存大小
  14. 【转360】KB4041678 Windows 仅安全更新(2017.10) 补丁更新后执行SQL出错! http://bbs.360.cn/thread-15201531-1-1.html
  15. 认识flask框架
  16. hive orc update
  17. php 判断两个时间段是否有交集
  18. jQuery before 和 after
  19. web.xml listener配置
  20. LeetCode 中级 - 组合总和II(105)

热门文章

  1. CentOS 7中安装 MySQL 出现了 No package mysql-server available. Error: Nothing to do 错误
  2. 全文检索框架---Lucene
  3. webpack 中那些最易混淆的 5 个知识点
  4. 从零开始学习MySQL全文索引
  5. 学Python必背的初级单词,你都背了吗?
  6. LINQ标准查询运算符的执行方式-即时
  7. 记一次Postgres CPU爆满故障
  8. Centos7 安装Python3.7
  9. JN_0019:CMD命令窗口常用操作
  10. Android实战项目——家庭记账本(六)