js中this指向问题总结
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的执行步骤
创建一个新的内存空间,放入一个空的对象
将this指向这个对象
执行构造函数的代码,为对象创建属性和方法
返回创建的对象
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指向问题总结相关推荐
- JavaScript面向对象(一)——JS OOP基础与JS 中This指向详解
前 言 学过程序语言的都知道,我们的程序语言进化是从"面向机器".到"面向过程".再到"面向对象"一步步的发展而来.类似于汇编语言这样的面 ...
- 关于js中this指向复习
简单说this指向 谁调用指向谁 1.对象.方法() 中,方法中的this指向的就是对象 2.普通函数中的 this 指向window,这是因为 window 是JS中的顶级对象,可以通过window ...
- JS中this指向问题
首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...
- 前端学习辑录(2):JS中this指向的问题
目录 this指向的不同场景: 一.普通函数调用 二.定时器函数 三.构造函数调用 四.对象方法调用 五.原型对象调用 总结 this指向的不同场景: 一.普通函数调用 普通函数中的this是谁?== ...
- js中this指向是什么以及指向谁
首先window是浏览器中最大的对象,所有的对象都在window中,在使用时可以省略 全局环境中的this指向window对象 我们声明的变量,最后都会变成window对象的属性 我们声明的函数,最后 ...
- 彻底理解js中this的指向
首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...
- js中修改this的指向方法整理
JavaScript(简称"JS") 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言.虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,Ja ...
- 随笔——js中的this指向,apply()与 call()
js中apply和Math.max()函数(原文) apply() Function.apply() 是JS的一个OOP特性,一般用来模拟继承和扩展this的用途,对于上面这段代码,可以这样去理解: ...
- 理解js中的this指向以及call,apply,bind方法
<script> function a(){var user = "追梦子";console.log(this.user); //undefinedconsole.lo ...
最新文章
- Winform中DataGridView绑定IList数据源后的排序
- 中国有替代w ndows的产品吗,电信将引入多款Wndows Phone手机 打造年轻品牌“飞Young”...
- CentOS 7源码安装httpd服务
- 台式计算机键盘配置及价格,最新台式电脑组装配置单及价格【图文】
- python scoket、SocketServer简单实现文件上传下载
- PS教程第一课:PS简介
- java安全密钥_Java安全性:密钥大小或默认参数非法?
- 8、周期性任务、find、break和continue 学习笔记
- python实用模块(持续更新)
- “长按地址在浏览器中打开”的解决办法
- Unity Shader - CheckerBoard(棋盘格) 等 Pattern 的测试
- 在SQL Sever中使用form membership认证
- 【论文笔记】Semantic Parsing on Freebase from Question-Answer Pairs
- 【每日一读】Pro-GNN:Graph Structure Learning for Robust Graph Neural Networks
- TX2/Linux下can总线的接收与发送详解!(回环测试)
- LayaAir之制作迷宫
- naoqi机器人不说话
- STM32WB55_NUCLEO开发(2)----使用STM32CubeMX 生成的简单 BLE 应用程序连接手机APP
- 设置afni环境变量—打开afni加载默认的大脑模板
- Python读取PSV