1. 默认绑定规则

(1) 全局作用下 this指向window
console.log(this);
(2) 函数独立调用下 this指向window
function test(){
console.log(this);
}
test()

2. 隐式绑定规则

  • object.fun() 对象的方法,this指向调用这个方法的对象

函数执行,this才会指向,才有意义,每一个函数执行都会有一个自身的this指向。 函数不执行,this没意义。每个this都代表着函数的执行。

var a = 0;var obj = {a: 2,foo: function(){console.log(this);   //objfunction test(){console.log(this); //window}test();}}obj.foo()

答案
obj.foo()方法执行 到 log(this) 此时的this指向调用这个方法的对象obj
test() 函数执行, 此时是函数的独立调用,因此this指向window

  • 函数立即执行语句: 在浏览器中this指向window
 // 立即执行函数// 第一种写法(function(){})()(function(){console.log(this);  })();// 第二种写法(function(){}())(function(){console.log(this);}())
  • 案例
var a = 0;var obj = {a: 2,foo: function(){function test(){console.log(this); }return test;}}obj.foo()()

答案:this指向window
分析: obj.foo()执行完毕返回test,然后变成了test()这仍是以一个函数的独立调用,所以this指向window

  • 变量赋值的情况
var a = 0;function foo(){console.log(this);}var obj = {a: 2,foo: foo}obj.foo()  //  指向objvar bar = obj.foo;   //指向windowbar()

答案分析:
改代码等价于

var obj = {a: 2,foo: function(){console.log(this)}}

obj.foo() 这属于对象的方法调用,所以this指向调用该方法的对象obj
2)

//var bar = obj.foo 等价于
var bar = function(){console.log(this)
}
bar() //这属于函数的独立调用,所以this指向window

(5) 参数赋值

 var a=0;function foo(){console.log(this);}function bar(fn){console.log(this);  //这个是函数bar的this 指向windowfn();}var obj = {a:2,foo:foo}bar(obj.foo)

答案分析
此时obj.foo是一个形参, 代表foo函数 所以fn()就等于foo() 属于独立调用,this指向window

3. 显示绑定(强绑定)

call(this指向的对象,参数1,参数2…)
apply(this指向的对象,[参数1,参数2…])
bind(this指向的对象)(参数1,参数2…)

undefine、 null无包装类,如果将其作为this指向对象则绑定失败,采用默认的绑定方式window

4. new绑定

function Person(){
//构造函数 和new一起使用才起效果
}
new Person()
new的执行步骤

  1. 创建一个新的内存空间,放入一个空的对象

  2. 将this指向这个对象

  3. 执行构造函数的代码,为对象创建属性和方法

  4. 返回创建的对象

  5. this绑定的优先级
    new绑定>显式绑定>隐式绑定>默认绑定
    (1) 默认绑定规则优先级最低
    (2)隐式和显示的比较

 // 优先级的比较function foo(){console.log(this);}var obj1 = {a:2,foo:foo}var obj2 = {a:3,foo:foo}// 1. 隐式绑定// obj1.foo()// 2. 显示绑定obj1.foo.call(obj2)obj2.foo.call(obj1)

结果
{a: 3, foo: ƒ}
{a: 2, foo: ƒ}
结果显示
obj1.foo.call(obj2) 前半部分属于隐式绑定,后又用了显式绑定,this指定了显式绑定的对象,因此,显式绑定的优先级>隐式绑定
(3)显式绑定和new 绑定的比较

 function foo(b){this.a = b}var obj1 = {};var bar = foo.bind(obj1)bar(2)console.log(obj1.a);var baz = new bar(3);console.log(obj1.a);console.log(baz.a);

答案分析
var bar = foo.bind(obj1) 属于函数的赋值,并且this强制指向了obj1
bar(2) 执行bar ,将2传入foo函数,执行obj1.a = 2
log(obj1.a) 输出2
var baz = new bar(3) new中this指向的是新创建的对象baz,bar强制指向了obj1,因为new的优先级>显式绑定,所以this指向了baz,执行baz.a = 3;
所以在输出obj1.a为2. baz.a =3

6. 箭头函数的this

(参数1, 参数2)=>{
函数体)
=>代表了function关键字

(1)
箭头函数的内部并没有this指向,箭头函数的this指向是由外层函数的作用域决定的。

   var a = 0;function foo(){// var that = this;console.log(this);var test = () => {console.log(this);}test(); }var obj1 = {a:2,foo:foo}obj1.foo();

输出结果: this指向了obj1
{a: 2, foo: ƒ}
{a: 2, foo: ƒ}

(2)

var a = 0;function foo() {console.log(this);var test = () => {console.log(this);}return test;}var obj1 = {a: 1,foo: foo}var obj2 = {a: 2,foo: foo}obj1.foo()();

分析:
此时的obj1.foo()执行第一个log(this)this指向obj1,并返回test ,即得到test()独立调用函数,但是默认绑定规则对箭头函数无效,因此test函数体内的this并不指向window,箭头函数没有this,它只能那他的父级作用域所指向的this,因此依旧指向obj1

(3)
var obj1 = {
a: 1,
foo: ()=>{
console.log(this);
}
}

    obj1.foo()

答案分析:
如果foo不是箭头函数,那么this指向obj1, 但是因为箭头函数内部没有this指向,因此取其父级找,这里的父级是全局,所以this指定window

总结:
所有的this绑定对箭头函数不适用
箭头函数内部的this指向取决于其父级的this(保持一致)

练习
// 综合大练习

var name = 'window'var obj1 = {name:'1',fn1: function(){console.log(this.name);},fn2: () => console.log(this.name),fn3: function(){return function(){console.log(this.name);}},fn4: function(){return () => console.log(this.name);}}var obj2= {name:'2'}obj1.fn1()obj1.fn1.call(obj2);obj1.fn2()obj1.fn2.call(obj2)obj1.fn3()()obj1.fn3().call(obj2)obj1.fn3.call(obj2)obj1.fn4()()obj1.fn4().call(obj2)obj1.fn4.call(obj2)()

答案解析:
obj1.fn1() 隐式绑定,this指向obj1 所以this.name = obj1.name = ‘1’
obj1.fn1.call(obj2) 显示绑定, this强制指向obj2, 所以this.name = obj2.name = ‘2’
obj1.fn2() 和 obj1.fn2.call(obj2)
fn2 方法是箭头函数,没有自己的this指向,各种绑定均失效,其this取决于其父级,这里父级是全局作用域,因此this.name = window.name = window

obj1.fn3()() 其中obj1.fn3()是调用函数,返回值为一个函数f,
function(){
console.log(this.name);
}
f()为再调用这个函数,为单独函数调用,this指向window返回window
obj1.fn3().call2 可以这样理解
var foo = obj.fn3 = function (){ log(this.name)} 函数的声明
obj1.fn3.call(oj2)它改变的是fn3这个父级的this指向,但返回的仍是一个函数f ,f()调用仍为函数的单独调用 返回window

fn4: function(){
return () => console.log(this.name);
}

var foo = obj1.fn4();
即 foo = () => console.log(this.name) 函数的定义
obj1.fn4()() == foo() 箭头函数 其父级fn4,fn4是通过隐式绑定this指向obj1 ,所以返回obj1.name = ‘1’
obj1.fn4().call(obj2) == foo.call(obj2) 仍未箭头函数,各种绑定失效,返回其父级的指向 obj1 返回‘1’
obj1.fn4.call(obj2)() == foo.call() 但是强制将foo的父级fn4的指向到了obj2 返回obj2.name = ‘2’

js中this指向问题总结相关推荐

  1. JavaScript面向对象(一)——JS OOP基础与JS 中This指向详解

    前  言 学过程序语言的都知道,我们的程序语言进化是从"面向机器".到"面向过程".再到"面向对象"一步步的发展而来.类似于汇编语言这样的面 ...

  2. 关于js中this指向复习

    简单说this指向 谁调用指向谁 1.对象.方法() 中,方法中的this指向的就是对象 2.普通函数中的 this 指向window,这是因为 window 是JS中的顶级对象,可以通过window ...

  3. JS中this指向问题

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  4. 前端学习辑录(2):JS中this指向的问题

    目录 this指向的不同场景: 一.普通函数调用 二.定时器函数 三.构造函数调用 四.对象方法调用 五.原型对象调用 总结 this指向的不同场景: 一.普通函数调用 普通函数中的this是谁?== ...

  5. js中this指向是什么以及指向谁

    首先window是浏览器中最大的对象,所有的对象都在window中,在使用时可以省略 全局环境中的this指向window对象 我们声明的变量,最后都会变成window对象的属性 我们声明的函数,最后 ...

  6. 彻底理解js中this的指向

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...

  7. js中修改this的指向方法整理

    JavaScript(简称"JS") 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言.虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,Ja ...

  8. 随笔——js中的this指向,apply()与 call()

    js中apply和Math.max()函数(原文) apply() Function.apply() 是JS的一个OOP特性,一般用来模拟继承和扩展this的用途,对于上面这段代码,可以这样去理解: ...

  9. 理解js中的this指向以及call,apply,bind方法

    <script> function a(){var user = "追梦子";console.log(this.user); //undefinedconsole.lo ...

最新文章

  1. Winform中DataGridView绑定IList数据源后的排序
  2. 中国有替代w ndows的产品吗,电信将引入多款Wndows Phone手机 打造年轻品牌“飞Young”...
  3. CentOS 7源码安装httpd服务
  4. 台式计算机键盘配置及价格,最新台式电脑组装配置单及价格【图文】
  5. python scoket、SocketServer简单实现文件上传下载
  6. PS教程第一课:PS简介
  7. java安全密钥_Java安全性:密钥大小或默认参数非法?
  8. 8、周期性任务、find、break和continue 学习笔记
  9. python实用模块(持续更新)
  10. “长按地址在浏览器中打开”的解决办法
  11. Unity Shader - CheckerBoard(棋盘格) 等 Pattern 的测试
  12. 在SQL Sever中使用form membership认证
  13. 【论文笔记】Semantic Parsing on Freebase from Question-Answer Pairs
  14. 【每日一读】Pro-GNN:Graph Structure Learning for Robust Graph Neural Networks
  15. TX2/Linux下can总线的接收与发送详解!(回环测试)
  16. LayaAir之制作迷宫
  17. naoqi机器人不说话
  18. STM32WB55_NUCLEO开发(2)----使用STM32CubeMX 生成的简单 BLE 应用程序连接手机APP
  19. 设置afni环境变量—打开afni加载默认的大脑模板
  20. Python读取PSV

热门文章

  1. 让狙击肺炎疫情稳准狠?春运返程中地图大数据的N种姿态
  2. AIX 部分故障判断及解决方法
  3. 京东方要向苹果供应OLED面板还差好几步
  4. SAP实施方法论之探讨-现状调研与需求分析_v1
  5. CSS 5 CSS 内联元素 和 块状元素
  6. linux svn怎么更新文件,linux安装SVN以及同步更新到项目上
  7. 62、63 不同路径
  8. Java调用发微博API_编写调用新版浪微博API的Java程序来发送微博
  9. Springboot3.0 打包后,tomcat启动失败
  10. 数学建模之找数据网站