JavaScript中this的理解(二)
三.修改this指向的方式。
1.利用call,apply,bind方法。
函数下面有三个方法,call,apply,bind都可以改变this的指向,下面我们来具体演示这三个方法的应用和区别。
call方法:
call方法的第一个参数就是新的this指向, 从第二个参数开始表示函数自身的参数。
const obj = {
a: 100,
};
function sum(x, y) {
console.log(this.a + x + y);
}
sum(3,7);//underfined + 3 + 7 = NaN
解析:直接调用,this指向window,window下面没有a属性,所以window.a是undefined
sum.call(obj, 3, 7); //100 + 3 + 7 = 110
解析:通过call改变this,让其指向obj,obj下面具有a属性,所以obj.a是100
apply方法:
apply方法的第一个参数就是新的this指向, 第二个参数是一个数组或者类数组,里面的值依然是函数自身的参数。
const obj = {
a: 100,
};
function sum(x, y) {
console.log(this.a + x + y);
}
sum(3,7);//underfined + 3 + 7 = NaN
解析:直接调用,this指向window,window下面没有a属性,所以window.a是undefined
sum.apply(obj, [3, 7]); //100 + 3 + 7 = 110 注意中括号是apply的第二个参数必须是数组或者类数组。
解析:通过apply改变this,让其指向obj,obj下面具有a属性,所以obj.a是100
call和apply的简单应用
var obj1 = {
name: 'zhangsan'
};
var obj2 = {
name: 'lisi'
};
window.name = 'window';
var getName = function(){
alert ( this.name );
};
getName(); // 输出: window
getName.call( obj1 ); // 输出: zhangsan
getName.call( obj2 ); // 输出: lisi
bind方法:
bind方法的第一个参数就是新的this指向, 从第二个参数开始表示函数自身的参数,但bind 是返回对应函数体,便于稍后调用,apply、call则是立即调用
const obj = {
a: 100,
};
function sum(x, y) {
console.log(this.a + x + y);
}
sum(3,7);//underfined + 3 + 7 = NaN
解析:直接调用,this指向window,window下面没有a属性,所以window.a是undefined
sum.bind(obj, 3, 7)(); //100 + 3 + 7 = 110 注意这里需要再次调用
解析:通过bind改变this,让其指向obj,obj下面具有a属性,所以obj.a是100
bind的使用场景
案例:将fn函数内部的this指向obj对象,2s后输出this.num的值。
window.num = 100; //window添加属性
const obj = {
num: 1000
}
function fn() {
console.log(this.num);
}
fn(); //100 这里的this指向window
window.setInterval(fn.call(obj), 2000); //此时的定时器无效,已经调用fn函数,
window.setInterval(fn.apply(obj), 2000); //此时的定时器无效,已经调用fn函数
window.setInterval(fn.bind(obj), 2000); //定时器的第一个参数是函数体或者函数名称,bind返回的就是函数体,所以吻合需求。
2.将正确的this存储。
通过变量将需要的this存储下来,然后在函数内部利用存储的this达到我们的目标。
window.num = 2;
function fn() {
console.log(this.num);
}
const obj = {
num: 1,
shownum: function() {
let _this = this;// 通过变量将需要的this存储下来
return function() {
console.log(_this.num); //调用存储的this
}
}
}
obj.shownum();
3.借用其他对象的方法
借用其他对象方法的第一种场景是借用构造函数,通过这种技术,可以实现一些类似继承的效果:
let A = function( name ){
this.name = name;
};
let B = function(){
A.apply( this, arguments );
};
B.prototype.getName = function(){
return this.name;
};
var b = new B( 'zhangsan' );
console.log( b.getName() ); // 输出: 'zhangsan'
借用其他对象方法的第二种场景是借用arguments
我们知道函数的参数列表arguments是一个类数组对象,虽然它也有“下标”,但它并非真正的数组,所以也不能像数组一样,进行排序操作或者往集合里添加一个新的元素。这种情况下,我们常常会借用Array.prototype对象上的方法。比如想往arguments中添加一个新的元素,通常会借用
Array.prototype.push:
(function(){
Array.prototype.push.call( arguments, 3 );
console.log ( arguments ); // 输出[1,2,3]
})( 1, 2 );
在操作 arguments 的时候,我们经常非常频繁地找 Array.prototype 对象借用方法。
四.和this相关的一些经典案例解读
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());//"The Window"
解析:
var声明的变量是window下面的属性
object对象里面存在方法getNameFunc,而且这个方法的返回值也是一个函数,必须再次调用。
通过返回的函数里面存在this,但是这里的this不是通过object进行调用,因为object.getNameFunc()返回的是一个函数体(普通的函数表达式),需要对函数体进行再次调用,而再次调用就和object对象没有关系了,所以这里的this不会指向object,而是指向window,结果输出"The Window"
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var _this = this;
return function(){
return _this.name;
};
}
};
alert(object.getNameFunc()()); //"My Object"
解析:
这里大部分情况和上面的一致,区别是object.getNameFunc方法里面提前将指向object对象的this存储为变量,并且在返回函数体的时候使用了这个变量,所以返回的函数中的this就是object.getNameFunc方法里面的this,即指向了object对象,结果输出 "My Object"
猜你喜欢LIKE
相关推荐HOT
更多>>article标签是什么元素?有什么作用
article标签是 HTML5 中的元素,用于定义一个独立的、完整的内容单元,通常包含文章、博客、新闻、评论等内容。增强可读性:使用 标签可以使页...详情>>
2023-04-20 16:19:55什么是linux系统内核?什么是linux发行版
Linux 是一个开源操作系统,由内核和许多其他的软件组成。其中,Linux 内核是操作系统的核心,负责管理计算机的硬件资源和提供基本的系统功能,...详情>>
2023-03-03 10:57:37数据埋点(Data buried point)的应用价值剖析
数据埋点指在应用中特定的流程中收集一些信息,用来跟踪应用使用的状况,后续用来进一步优化产品或是提供运营的数据支撑。比如访问数(Visits),...详情>>
2023-02-08 17:38:00web前端技术干货-iframe
在这个网页中,同时在一个页面中展示了三个网站:千锋教育官网、千锋教育HTML5大前端官网、千锋教育HTML5大前端好程序员官网。这是如何做到的呢...详情>>
2022-12-27 16:23:13热门推荐
java异常分类三大类是什么?
沸常用的maven打包命令有哪些?
热article标签是什么元素?有什么作用
热js引用数据类型有哪些
新什么是枚举?没有枚举之前怎么做的
javascript中如何搜索数组元素
css阴影效果属性:box-shadow属性
echarts和chart的优缺点对比
mybatis通用mapper的使用方法
ui设计之js效果-如何制作文字倒计时
svn与git的区别是什么?使用git的优势是什么
什么是linux系统内核?什么是linux发行版
Linux三剑客之-sed
JumpServer堡垒机部署及恢复