-
2022-01-13 16:47:33
this
解析器在调用函数时,每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就是 this,this指向的是一个对象,这个对象我们称为函数执行的上下文对象。
函数内this的指向
我们都知道,函数的调用有六种形式。
根据函数的调用方式的不同,this会指向不同的对象:
-1.以函数的形式(包括普通函数、定时器函数、立即执行函数)调用时,this的指向永远都是window。比如fun();相当于window.fun();
-2.以方法的形式调用时,this指向调用方法的那个对象
-3.以构造函数的形式调用时,this指向实例对象
-4.以事件绑定函数的形式调用时,this指向绑定事件的对象
-5.使用call和apply调用时,this指向指定的那个对象
function fun(){ console.log(this); console.long(this.name); } var obj1 = { name:'smyh', sayName:fun }; var obj2 = { name:'vso', sayName:fun }; var name = '全局name属性'; fun();
打印结果:
window 全局name属性
上面的举例可以看出,this指向的是window对象,所以this。name指的是全局的name。
function fun(){ console.log(this); console.log(this.name); } var obj1 = { name:'smyh', sayName:'fun' }; var obj2 = { name:'cad', sayName:'fun' }; var name = '全局name属性'; obj2.sayName();
打印结果:
Object cad
上面的举例可以看出,this指向的对象是obj2,所以this.name指的是obj2.name。
箭头函数中this的指向
ES6中的箭头函数并不会使用上面的准则,而是会继承外层函数调用的this绑定(无论this绑定到什么)。
改变函数内部的 this指向
JS专门为我们提供了一些方法来改变函数内部的this指向。如:call()、apply()、bind()方法。
更多相关内容 -
JS中改变this指向的方法(call和apply、bind)
2020-10-22 15:59:15this是javascript的一个关键字,随着函数使用场合不同,this的值会发生...但是总有一个原则,那就是this指的是调用函数的那个对象,通过本文给大家介绍JS中改变this指向的方法(call和apply、bind),需要的朋友参考下 -
详解JS中定时器setInterval和setTImeout的this指向问题
2020-10-20 17:02:03在js中setTimeout和setInterval都是用来定时的一个功能,下面这篇文章主要给介绍了JS中setInterval和setTImeout的this指向问题,文中通过示例介绍的很详细,有需要的朋友可以参考借鉴,一起来看看吧。 -
解决使用attachEvent函数时,this指向被绑定的元素的问题的方法
2020-10-30 18:13:25解决使用attachEvent函数时,this指向被绑定的元素的问题的方法 -
函数四种调用模式以及其中的this指向
2020-08-31 15:56:36本文主要介绍了函数四种调用模式以及其中的this指向的相关知识,具有一定的参考价值,下面跟着小编一起来看下吧 -
javascript中this指向详解
2020-10-22 12:31:35this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象,接下来我会深入的探讨这个问题。 -
关于JavaScript中的this指向问题总结篇
2020-12-09 14:59:052:一般情况下this指向它的调用者 3:es6的箭头函数中,this指向创建者,并非调用者 4:通过call、apply、bind可以改改变this的指向 下面我们具体分析一下 1:在函数调用时 (非严格模式) const func = function () {... -
深入理解js函数的作用域与this指向
2021-01-19 15:18:13函数的作用域与this指向是js中很重要的一部分,理清这点东西需要个逻辑,看看我的逻辑怎么样… 下面是个提纲,可以直接挑你感兴趣的条目阅读。 • 函数的定义方式:直接定义(window下,内部定义),对象的方法,... -
详解vue中的computed的this指向问题
2020-10-17 16:09:46主要介绍了详解vue中的computed的this指向问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
我所理解的JavaScript中的this指向
2020-10-14 19:41:44主要介绍了JavaScript中this指向的相关资料,帮助大家更好的理解和学习JavaScript,感兴趣的朋友可以了解下 -
this指向,并改变this指向
2022-01-19 19:58:37不同场景下的this指向问题 window 对象 函数 类不同场景下的this指向问题
window
在js文件中直接打印this
console.log(this); // window
浏览器中如下:
对象
1、首先创建一个平平无奇 对象,在方法中打印this:
const obj = { name: 'wang', age: 18, play: 'pingpang', baseInfo: function() { console.log(this); // obj对象 console.log(this.name + '的年龄是' + this.age ); // wang的年龄是18 } } obj.baseInfo()
浏览器打印如下:
因此:调用对象的方法,this指向对象本身
2、下一步,我们改造上面obj,改变[‘play’]的值,并创造 一个新属性
const obj = { name: 'wang', age: 18, play: 'pingpang', likes: function() { this.play = 'basketball' console.log(this); // 更改后的 obj对象 this.likeType = '有氧' console.log(this.name + ' like ' + this.play +'。并喜爱' + this.likeType); // wang like basketball。并喜爱有氧 } } obj.likes()
打印如下:
因此,this指向对象时,改变原有对象的key值,或创建一个新的key,此时this指向被改变之后的对象3、上面我们测试了对象中的普通函数,如果换成 箭头函数 呢?继续改造obj:
const obj = { name: 'wang', age: 18, play: 'pingpang', test: () => { console.log(this); // window 对象 this.testA = '语文' console.log(this.name + ' 喜欢的课程是' + this.testA); // 喜欢的课程是语文 } } obj.test()
打印如下:
因此:调用对象的箭头函数方法,this的指向是window,不能再如第二步改变 play 的值一样改变 name,所以上面打印不是 “wang喜欢的课程是语文” 而是 “喜欢的课程是语文”。4、如果我们进一步改造obj的方法,测试下在setTimeout里的this指向呢?
const obj = { name: 'wang', age: 18, play: 'pingpang', testSetTimeout: function() { setTimeout(function() { console.log('setTimeout(function(){})=======', this) // window console.log(this.play) },5) setTimeout(() => { console.log('setTimeout(()=>{})=======', this) // obj console.log(this.play) },10) } } obj.testSetTimeout()
打印如下:
这里的结果似乎有些出乎意料~
调用对象的方法:
setTimeout里回调是普通函数时,this的指向是window
setTimeout里回调是箭头函数时,this的指向是对象本身函数
创建一个普通函数
function testFunc(){ console.log(this); this.num1 = 20; console.log('this.num1: ', this.num1); // 20 } // 调用1 testFunc() // window // 调用2 let test2 = testFunc() test2() // window
打印如下:
因此,在普通函数中,this指向window类
1、创建一个类
class fatherObj { constructor(name, age){ this.name = name this.age = age } showText(){ console.log(this) // fatherObj return '姓名是:' + this.name + ',年龄是:' + this.age } } const fatherObj_C = new fatherObj('wang', 18) console.log(fatherObj_C.showText()) // 姓名是:wang,年龄是:18
打印如下:
因此,在类里使用this,this指向类本身2、进一步改变类的方法 showText,我们来改变name的值来查看变化
class fatherObj { constructor(name, age){ this.name = name this.age = age } showText(){ this.name = '小王' console.log(this) // 新fatherObj return '姓名是:' + this.name + ',年龄是:' + this.age } } const fatherObj_C = new fatherObj('wang', 18) console.log(fatherObj_C.showText()) // 姓名是:小王,年龄是:18
打印如下:
由此可见,this指向的是更新之后的类3、保留第2步的fatherObj类,我们进一步测试,创建它的子类
class sonObj extends fatherObj { constructor(name, age, sex){ super(name, age) this.sex = sex } showMore(){ console.log(this) return super.showText()+' ,性别是:' + this.sex } } const son_C = new sonObj("xiaowang", 5, 'nv') console.log('son_C: ', son_C.showMore());
打印如下:
因此,在类里,this始终指向的是类本身。也很清晰看到,子类sonObj的原型上是父类fatherObj改变this的指向
前置代码,先码个对象和函数吧~
const testFunc = function(params1, params2) { console.log(this) console.log('params1: ', params1); console.log('params2: ', params2); return {name: 'wang'} } const testObj = { p1: 11, p2: 22, showThis(params){ console.log('showThis=====', this, params) } }
如果我们调用
testFunc()
和testObj.showThis()
,this的指向应分别是window
和testObj
吧。
下面,我们来看看改变this的指向~call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象
call
1、改变testFunc的this指向:
testFunc.call(testObj, 3,4) // {p1: 11, p2: 22, showThis: ƒ} // params1: 3 // params2: 4 testFunc.call(testObj, 'test2') // {p1: 11, p2: 22, showThis: ƒ} // params1: test2 // params2: undefined testFunc.call(testObj) // {p1: 11, p2: 22, showThis: ƒ} // params1: undefined // params2: undefined testFunc.call() // window // params1: undefined // params2: undefined testFunc.call(null) // window // params1: undefined // params2: undefined testFunc.call(undefined) // window // params1: undefined // params2: undefined testFunc.call(2) // Number{2} // params1: undefined // params2: undefined
2、改变testObj的指向
testObj.showThis.call(testFunc()) // Window {…} // params1: undefined // params2: undefined // showThis===== {name: 'wang'} undefined testObj.showThis.call(testFunc(), 18) // showThis===== {name: 'wang'} 18
apply
apply 和 call 的区别在于,apply的参数要放在数组里传过去,call的参数直接放进去
testFunc.apply(testObj, [1,2]) // {p1: 11, p2: 22, showThis: ƒ} // params1: 1 // params2: 2 testFunc.apply([1,2]) // [1, 2] // params1: undefined // params2: undefined testFunc.apply(undefined) // Window {…} // params1: undefined // params2: undefined
bind
bind 除了返回是函数需要自调用外,它的参数和 call 一样。
testFunc.bind(testObj, 3, 4)() // {p1: 11, p2: 22, showThis: ƒ} // params1: 3 // params2: 4
参考文章:
1、this的指向
2、call、apply、bind的用法 -
彻底搞懂js中的this指向
2022-02-04 11:39:06js中的this指向问题经常容易让人混淆,特别是在ES6引入箭头函数后,对于标准函数中的this指向和箭头函数中的this指向就更让人费解。 本文总结了js中标准函数和箭头函数的this指向问题,帮助大家理清js中的this指向...js的this指向
js中的this指向问题经常容易让人混淆,特别是在ES6引入箭头函数后,对于标准函数中的this指向和箭头函数中的this指向就更让人费解。
- 本文总结了js中标准函数和箭头函数的this指向问题,帮助大家理清js中的this指向。
- 并且介绍几个改变this指向的方法,改变this指向不管是在js的继承还是js的函数中都是很重要的。
一 抓住核心
我在网上看过一些关于this指向的博客,很多都是通过例子就直接开始讲解,虽然这样也可以帮助读者快速了解,但是在这里,我希望由一般到特殊,先指出标准函数和箭头函数中this指向的不同,再通过例子讲解来验证。
刚开始可能看不太懂,但是经过例子的讲解,就会逐渐理解。
- 对于标准函数中的this:
this
引用的是把函数当成方法调用的上下文对象。标准函数中的this指向是当我们调用函数的时候确定的,调用方式的不同决定了this
的指向不同,一般指向我们的调用者。直白点就是:哪个对象调用函数,函数里面的this指向哪个对象。 - 对于箭头函数中的this:
this
引用的是定义箭头函数的上下文。箭头函数不会创建自己的this
, 所以它没有自己的this
,它只会在自己作用域的上一层继承this
。所以箭头函数中this的指向在它在定义时已经确定了,之后不会改变。
二 标准函数中的this
核心是:哪个对象调用函数,函数里面的
this
指向哪个对象。只不过window作为浏览器中的全局对象,在调用函数时经常是省略的,有时候很多this指向的例子看起来奇怪的原因,就是因为window对象的省略。
下面的表格列出了在标准函数中不同调用方式的this指向,从中也可以间接知道一般在调用什么函数时用到window对象。
调用方式 this指向 普通函数调用 window 构造函数调用 实例对象,原型对象里面的方法也指向实例对象 对象方法调用 该方法所属对象 事件绑定方法 绑定事件对象 定时器函数 window 立即执行函数 window 函数的不同调用方式决定了this 的指向不同,下面是一些例子:
① 普通函数 this 指向window
<script> username = 'rs'; function fn() { console.log('普通函数的this' + this); console.log(this.username); } fn(); //相当于window.fn() </script> //输出结果: //普通函数的this[object Window] //rs
② 对象的方法 this指向的是对象 o
<script> color = 'red'; var o = { color: 'blue', sayHi: function() { console.log('对象方法的this:' + this); console.log('color:' + this.color); } } o.sayHi(); </script> //输出结果: //对象方法的this:[object Object] //color:blue
③ 构造函数 this 指向 subClass 这个实例对象
<script> let TestClass=function(){ this.name='111'; } let subClass=new TestClass(); subClass.name='cn'; console.log(subClass.name);//cn let subClass1=new TestClass(); console.log(subClass1.name)//111 </script>
④ 绑定事件函数 this 指向的是函数的调用者 btn这个按钮对象
<body> <button>点击</button> <script> var btn = document.querySelector('button'); btn.onclick = function() { console.log('绑定时间函数的this:' + this); }; </script> </body> //点击button,输出结果 //绑定时间函数的this:[object HTMLButtonElement]
⑤ 定时器函数 this 指向的也是window
<script> window.setTimeout(function() { console.log('定时器的this:' + this); }, 1000); //定时器前面经常省略window,这点要注意 //虽然省略了window,但是其调用对象仍然是window,this指向window </script> //输出结果 //定时器的this:[object Window]
⑥ 立即执行函数 this还是指向window
<script> (function() { console.log('立即执行函数的this' + this); })(); </script> //输出结果 //立即执行函数的this:[object Window]
三 箭头函数中的this
核心是:箭头函数不会创建自己的
this
, 所以它没有自己的this
,箭头函数里面的this
是继承外面的环境 。所以箭头函数中this
的指向在它在定义时已经确定了,之后不会改变。有人可能对环境和作用域这样的概念不太熟悉,这里可以这样简单理解,
{}
内和函数内的就是个局部作用域或者局部环境,最外层就是全局作用域或者全局环境。例子①
var id = 'GLOBAL'; var obj = { id: 'OBJ', a: function(){ console.log(this.id); }, b: () => { console.log(this.id); } }; obj.a(); // 'OBJ',标准函数,this指向调用者obj obj.b(); // 'GLOBAL',箭头函数,继承外面作用域,也就是全局环境的this值 —— window
例子②
window.color = 'red'; let o = { color: 'blue' }; let sayColor = () => console.log(this.color); sayColor(); // 'red' o.sayColor = sayColor; o.sayColor(); // 'red' //对象o的方法sayColor是使用箭头函数定义的 //这个函数中的this就永远指向它定义时所处的全局执行环境中的this //即便这个函数是作为对象o的方法调用,this依旧指向Window对象。
例子③
let obj={ a:'rs', fn:function(){ setTimeout(function(){console.log(this.a)},1000); //相当于window.setTimeout(function(){console.log(this.a)},1000); } }; obj.fn();//undefined
不难发现,虽然 fn() 里面的 this 是指向 obj ,但是,传给 setTimeout 的是标准函数, this 指向是 window , window 下面没有 a ,所以这里输出 undefined。
换成箭头函数
let obj={ a:'rs', fn:function(){ setTimeout(()=>{console.log(this.a)},1000); } }; obj.fn();//'rs'
这次输出 rs 是因为,传给 setTimeout 的是箭头函数,然后箭头函数里面没有 this ,所以要向上层作用域查找,在这个例子上, setTimeout 的上层作用域是 fn。而 fn 里面的 this 指向 obj ,所以 setTimeout 里面的箭头函数的 this ,指向 obj ,所以输出rs。
四 改变函数内部this指向
- JavaScript 为我们专门提供了一些函数方法来帮我们处理函数内部 this 的指向问题,常用的有
bind(),call(),apply()
三种方法
4.1call() 方法
-
call()
方法调用一个对象,简单理解为调用函数的方式,但是它可以改变函数的this指向 -
fun.call(thisArg,arg1,arg2,.....)
-
thisArg
: 在 fun 函数运行时指定的 this 值 -
arg1,arg2
: 传递的其他参数 -
返回值就是函数的返回值,因为它就是调用函数
-
因此当我们想改变 this 指向,同时想调用这个函数的时候,可以使用 call,比如继承
<body> <script> // 1. call() var o = { name: 'andy' } function fn(a, b) { console.log(this); console.log(a + b); }; fn.call(o, 1, 2); // call 第一个可以调用函数 第二个可以改变函数内的 this 指向 // call 的主要作用可以实现继承 function Father(uname, age, sex) { this.uname = uname; this.age = age; this.sex = sex; } function Son(uname, age, sex) { Father.call(this, uname, age, sex); } var son = new Son('刘德华', 18, '男'); console.log(son); </script> </body>
4.2apply()方法
-
apply()
方法调用一个函数,简单理解为调用函数的方式,但是它可以改变函数的 this指向 -
fun.apply(thisArg,[argsArray])
-
thisArg
: 在 fun 函数运行时指定的 this 值 -
argsArray
: 传递的值,必须包含在数组里面 -
返回值就是函数的返回值,因为它就是调用函数
-
因此 apply 主要跟数组有关系,比如使用 Math.max() 求数组的最大值
<body> <script> // 2. apply() 应用 运用的意思 var o = { name: 'andy' }; function fn(arr) { console.log(this); console.log(arr); // 'pink' }; fn.apply(o, ['pink']); // 1. 也是调用函数 第二个可以改变函数内部的this指向 // 2. 但是他的参数必须是数组(伪数组) // 3. apply 的主要应用 比如说我们可以利用 apply 借助于数学内置对象求数组最大值 // Math.max(); var arr = [1, 66, 3, 99, 4]; var arr1 = ['red', 'pink']; // var max = Math.max.apply(null, arr); var max = Math.max.apply(Math, arr); var min = Math.min.apply(Math, arr); console.log(max, min); </script> </body>
4.3bind()方法
bind()
方法不会调用函数。但是能改变函数内部this
指向fun.bind(thisArg,arg1,arg2,....)
- 返回由指定的
this
值和初始化参数改造的 原函数拷贝 - 因此当我们只是想改变 this 指向,并且不想调用这个函数的时候,可以使用bind
<body> <button>点击</button> <script> // 3. bind() 绑定 捆绑的意思 var o = { name: 'andy' }; function fn(a, b) { console.log(this); console.log(a + b); }; //fn.bind(o,1,2); 不会像call和apply那样立即调用 var f = fn.bind(o, 1, 2); f(); // 1. 不会调用原来的函数 可以改变原来函数内部的this 指向 // 2. 返回的是原函数改变this之后产生的新函数 // 3. 如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向此时用bind // 4. 我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒钟之后开启这个按钮 var btn1 = document.querySelector('button'); btn1.onclick = function() { this.disabled = true; // 这个this 指向的是 btn 这个按钮 // var that = this; setTimeout(function() { // that.disabled = false; // 定时器函数里面的this 指向的是window,所以要用that代替 this.disabled = false; // bind()之后,定时器函数里面的this 指向的就是btn }.bind(this), 3000); // 这个this在function()外面 指向的是btn这个对象 } </script> </body>
4.4三个方法的区别
call
和apply
会调用函数,并且改变函数内部的this
指向call
和apply
传递的参数不一样,call 传递参数,apply 必须数组形式bind
不会调用函数,可以改变函数内部this
指向
4.5注意
call()、apply()、bind()等方法不能改变箭头函数中this的指向。
var id = 'Global'; let fun1 = () => { console.log(this.id) }; fun1(); // 'Global' fun1.call({id: 'Obj'}); // 'Global' fun1.apply({id: 'Obj'}); // 'Global' fun1.bind({id: 'Obj'})(); // 'Global'
-
关于this指向问题及改变this指向的方法
2021-10-24 09:10:25this指向详解 this的指向在函数定义的时候是确定不了的,只有函数执行的时候才确定this到底指向谁 一般情况下this指向调用它的对象 下面我们来看看this被调用时的五种情况 思维导图 分析 1.作为对象方法...this指向详解
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才确定this到底指向谁
一般情况下this指向调用它的对象
下面我们来看看this被调用时的五种情况
思维导图
分析
1.作为对象方法被调用
当函数作为对象方法被调用时this指向该对象
var obj = { age: 18, fn: function () { console.log(this === obj);//true console.log(this.age);//18 } } console.log(obj.fn());
2. 作为普通函数被调用时
this指向全局对象window
严格模式下 this被规定不会指向全局 则是undefined
window.age = 18; function fn() { console.log(this.age);//18 } fn()
3.作为构造函数被调用时
构造函数里面的this有点特殊 首先我们来了解一下构造函数跟普通函数的区别
//构造函数主要用来初始化对象 为对象的成员变量赋值初始值 他总于new一起使用
new在构造函数中做了哪些事
//1.在内存中创建一个新的对象
//2.让this指向这个新对象
//3.在构造函数里面的代码,给这个新对象添加属性和方法
//4.返回这个新对象 所以构造函数里面一般不需要return
了解之后我们再来看构造函数里面的this
构造函数里的this指向 new创建的实例化对象(没有return的情况下)
如果构造函数内出现了return并且是一个object对象那么最终的运算结果返回这个对象
只要构造函数不返回数据或者返回基本数据类型 this仍然指向实例
function Fn() { this.age = 18; //此时a.age是return的结果20 return { age: 20 } } let a = new Fn(); console.log(a.age);//20
4.箭头函数里面的this
箭头函数里面没有自己的this 他只会从自己的作用域链上一层继承this
this.age = 20; var obj = { age: 18, fn: () => { console.log(this.age);//20 } } obj.fn()
5.call&& apply&&bind
在function的原型上有三个方法 call apply bind,所有函数都是Function的实例,所以所有的函数都可以调用这三个方法,而这三个方法都是用来改变this指向的
call或apply调用
- 都是把函数立即执行改变函数中的this指向(第一个参数是谁this就是谁)
- apply同理 唯一的区别就是传参的格式不一样,apply把传递给函数的形参以数组的形式管理起来,最终的效果和call一样,也是把数组中的每一项作为实参,一个个的传递给函数
- 真实项目中建议大家使用call,因为其性能好一些(三个及以上参数,call的性能明显比apply好一些)
- this存储的值 null.undefined.对象
- 一个也不写,非严格模式下是window 严格模式下是undefined
- null 严格模式下是null非严格模式下是window
function fn(x, y) { console.log('加油'); console.log(this);//this指向window console.log(x + y); } var o = { name: 'andy' } fn.call()//call 呼叫 可以调用函数 fn.call(o, 1, 2)//第一个值是this指向, 后边实参 fn.apply(o, [10, 20])//apply传递数组 fn.call(10, 20)//this-->new Numbe(10) x-->20 y-->undefined
apply的应用小技巧 :获取数组中的最大值
let arr = [10, 20, 58, 79, 66] console.log(Math.max(arr));//NaN,要求传递数字,不是直接传递数组 console.log(Math.max(...arr));//es6中的展开运算符 console.log(Math.max.apply(Math, arr));
重新call方法
- fn基于__proto__找到Function.prototype.call 把call方法执行
- 在call方法执行的时候
- content: obj要改变的this指向, params;[10, 20]执行函数传递的实参 this: fn要执行的函数
-
它干的事情是立即把fn(this)函数执行,并且让fn(this)中的this指向obj, 把10,20(params)传递给fn(this),接收fn执行的返回结果,作为最后结果返回
思路:给content设置一个属性(例如:xxx,新增的属性不要和原始content中的属性冲突(symbbol唯一值属性)) 让属性值等于要执行的函数(即:this[fn]),后面基于content.xxx()执行,这样即把函数执行了 ,也让函数的的this改成了content
Function.prototype.call = function call(content, ...params) { // this-->fn content-->obj params-->[10,20] // 思路:给content设置一个属性(例如:xxx,新增的属性不要和原始content中的属性冲突(symbbol唯一值属性)) 让属性值等于要执行的函数(即:this[fn]),后面基于content.xxx()执行,这样即把函数执行了 ,也让函数的的this改成了content if (content == null) content = window//this指向为null时指向window // 如果是原始值,字符串设置属性值之后获取不到要变成object if (! /^objet|funcion$/.test(typeof content)) content = Object(content)// let self = this, key = Symbol('KEY'), result; content[key] = self; result = content[key](...params) // delete content[key]//新增的属性用完后记得移除 Reflect.deleteProperty(content, key)//es6中可以基于Reflect.deleteProperty移除对象的某个属性 return result } const fn = function fn(x, y) { console.log(this, x, y); return x + y } let obj = { name: 'obj' } let res = fn.call(obj, 10, 20) console.log(res); // fn基于__proto__找到Function.prototype.call 把call方法执行 // 在call方法执行的时候 // content: obj要改变的this指向, params;[10, 20]执行函数传递的实参 this: fn要执行的函数 //它干的事情是立即把fn函数执行,并且让fn中的this指向obj, 把10,20传递给fn,接收fn执行的返回结果,作为最后结果返回
bind
call VS bind
call是立即把函数执行,而bind只是预处理函数中的this和参数,不会立即执行
// 点击按钮 ,fn方法执行,我们想让其中的this变成obj ev事件对象也存在 在传递10/20
<button id="sumit">点击</button> const sumit = document.querySelector("#sumit") const fn = function fn(x, y, ev) { console.log(this, ev); } let obj = { name: 'obj' } sumit.onclick = fn;//点击按钮时this-->sumit x-->PointerEvent事件对象 // 点击按钮 ,fn方法执行,我们想让其中的this变成obj ev事件对象也存在 在传递10/20 // sumit.onclick = fn.call(obj, 10, 20)//这样处理是错误的,因为call把函数立即执行了 sumit.onclick = function (ev) { //先把事件行为绑定匿名函数,先执行匿名函数(获取ev对象)在匿名函数执行的时候this-->sumit,我们在让真正处理的fn函数执行,此时可以基于call方法改变this'了 fn.call(obj, 10, 20, ev) } sumit.onclick = fn.bind(obj, 10, 20)//这样就可以了
重写bind
<button id="sumit">点击</button> Function.prototype.bind = function bind(context, ...params) { let self = this; // this-->fn contexxt-->obj params-->[10,20] return function proxy(...args) { // args-->ev this-->sumit return self.call(context, ...params.concat(args)) } } const sumit = document.querySelector("#sumit") const fn = function fn(x, y, ev) { console.log(this, ev); } let obj = { name: 'obj' } sumit.onclick = fn.bind(obj, 10, 20)
总结
函数中的this指向
- 普通函数下this是window 严格模式下是undefined
- 对象或方法this指向调用者
- 构造函数里面的this指向实例对象(原型对象里面的this也指向实例对象 在本篇中没有展开)
- 箭头函数没有自己的this
- call和apply可以改变this指向
再来补充几条
- 绑定点击事件里面的this指向的是调用者
- 定时器里面的this指向window
- 立即执行函数里面的this指向window
由此我们可以得出)函数执行的时候,看它前面有没有点,如果有,点前面是谁,this就是谁,如果没有,就是window
----------------------------------------------完结散花-----------------------------------------------------------------------
----------------接受大佬们的批改和指点 ,欢迎留言------------------------------------------------------------------
-
js代码-封装函数 f,使 f 的 this 指向指定的对象
2021-07-16 12:41:07js代码-封装函数 f,使 f 的 this 指向指定的对象 -
Angular.JS中的this指向详解
2020-12-09 14:56:441、谁最终调用函数,this指向谁。 ① this指向的,永远只可能是对象!!!!!! ② this指向谁,永远不取决于this写在哪!!而是取决于函数在哪调用。 ③ this指向的对象,我们称之为函数的上下文context... -
this指向 箭头函数中的this call、apply和bind方法的用法以及区别
2021-01-08 10:02:40thisthis 指向看看箭头函数的案例call、apply和bind方法的用法以及区别来几个面试题试试 this 指向 1.普通函数的this:指向它的调用者,如果没有调用者则默认指向window. 2.箭头函数的this: 指向箭头函数定义时所处... -
js this指向
2021-01-08 17:44:05JavaScript this指向总结 在JavaScript中this永远指向当前函数的主人,即函数的调用对象或事件的调用对象,大致分为以下几种情况。 单独的this或者全局函数中的this指向window对象 console.log(this);//this => ... -
JavaScript有关this指向问题,如何修改this指向
2021-12-18 15:21:30JavaScript有关this指向问题 -
js中this指向的四种规则+ 箭头函数this指向
2021-01-20 23:31:44js中this指向的四种规则+ 箭头函数this指向 四种规则分别是:默认、隐式、显式(call、apply、bind)、new 对象 -
web前端高级JavaScript - JavaScript中函数内的this指向
2020-09-09 15:11:39函数内的this指向 下表中列出的这些this的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this的指向不同,一般情况下会指向函数的调用者(谁调用指向谁)。 调用方式 this指向 普通函数调用 ... -
javascript this指向相关问题及改变方法
2021-01-21 10:53:38在学习javascript中我们往往会被this的指向问题弄的头昏转向,今天我们就来学习一下this的指向问题,和改变this指向的方法。 一.this的指向问题 在学习this的指向问题之前我们需要明白两点: 1:this永远指向一个... -
JAVAscript中的this指向和this指向的修改
2021-04-08 19:09:09JAVAscript中的this指向和this指向的修改 this 关键字 一般在函数中使用,表示哪个对象执行了当前函数。 每一个函数内部都有一个关键字是 this 。 函数内部的 this 只和函数的调用方式有关系,和函数的定义方式没有... -
jQuery AJAX回调函数this指向问题
2020-12-13 01:39:09如在全局作用域调用一个含this的对象,此时当前对象的this指向的是window。为了让this的指向符合自己的意愿,JavaScript提供了两个方法用以改变this的指向,它们是call和apply,当然也有利用闭包来实现的方法。本文... -
JavaScript this指向相关原理及实例解析
2020-11-19 23:25:35记得初学 JavaScript 时,其中 this 的指向问题曾让我头疼不已,我还曾私自将其与闭包、原型(原型链)并称 JS 武林中的三大魔头。如果你要想在 JS 武林中称霸一方,必须将这三大魔头击倒。个人认为在这三大魔头中,... -
详解JavaScript的this指向和绑定
2020-11-19 18:28:50刚开始学习 JavaScript 的时候,this 总是最能让人迷惑,下面我们一起看一下在 JavaScript 中应该如何确定 this 的指向。 this 是在函数被调用时确定的,它的指向完全取决于函数调用的地方,而不是它被声明的地方... -
基于javaScript的this指向总结
2020-12-09 19:55:582:一般情况下this指向它的调用者 3:es6的箭头函数中,this指向创建者,并非调用者 4:通过call、apply、bind可以改改变this的指向 下面我们具体分析一下 1:在函数调用时 (非严格模式) const func = function () {... -
JavaScript This指向问题详解
2021-01-19 21:10:15这篇文章主要介绍了JavaScript This指向问题详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 各位小伙伴在面试中被面试官问道this指向问题一定不少吧,同时... -
JS-箭头函数及其this的指向和改变this指向(call apply bind)
2020-04-09 21:34:232,箭头函数的this指向 父级程序的this指向 如果父级程序有this指向(父级程序也是函数),this指向的就是父级程序的this指向 如果父级程序没有this指向(数组,对象....),this指向的是window 复习this指向 **************... -
this指向.html
2021-03-09 09:37:00看的很多视频总结的this指向问题 有代码展示、 四种绑定对应的四种调用