JS this的指向和改变方法
函数执行方式this的指向:
最基本的有三种
- 普通的函数调用,this 谁调用就指谁
function test () {
console.log(111);
console.log(this);
}
test();
this也是window, 表示默认是使用window调用
window.test();
- 作为对象的方法调用
var stu = {
name : "张三",
age : 23,
play : function() {
console.log("打篮球");
console.log(this)
}
}
stu.play();
在分析的时候, 不用去管函数或者方法是怎样声明的, 只需要看函数调用,
谁调用这个这个方法或者函数, 那么this就指向谁
a.
test = stu.play;
test();
window.test();
this指向的结果为:window
test = function() {
console.log("打篮球");
console.log(this)
}
b.
stu.play = test;
stu.play();
结果为:
111
{name:"张三",age:23,play:f}//this指向stu这个对象
- 作位构造函数配合new关键字使用
this指向new关键字创建的对象
function Person(name, age) {
this.name = name;
this.age = age;
console.log(this);
}
new Person("zhangsan",23);
注意:
左值 : 就是指能够写在赋值运算符左边的值 比如变量
右值 : 就是指能够写在赋值运算符右边的值
this不能作为左值,会报错
上述三种函数执行的方式 缺点: 就是不能改变this指向
改变this指向的方法
call
apply
bind
函数的上下文调用模式
var obj={
name:"张三",
age:23
}
function sum(n1, n2) {
console.log(n1 + n2);
console.log(this); // 我不让this指向window, 要让this指向obj
}
call ()
语法结构 : 函数名.call(this的新指向, 参数1, 参数2, …)
sum.call(obj,14, 3)
//结果为:17,{name:"张三",age:23}
apply()
语法结构 : 函数.apply(this的新指向, 参数数组或者伪数组)
注意 : apply方法只有两个参数
sum.apply(obj,[16, 8])
//结果为:24,{name:"张三",age:23}
bind()
语法结构 : 函数名.bind(this的新指向, 参数1, 参数2, …)
特点 :
1.不会指向这个要修改this指向的函数的函数, 而是返回已经修改了this指向的函数
2.bind不传参, 那么就在调用修改了this指向后的函数时传参, 但是如果两个都传了, 那么接受bind的参数
var fun = sum.bind(obj);
fun(15,8)
//结果为:23,{name:"张三",age:23}
var fun = sum.bind(obj,10,11);
fun(15,8)
//结果为:21,{name:"张三",age:23}
练习:
// 1.
setInterval(function() {
console.log(123);
console.log(this);
}, 1000); // this指的是window
// 2.
var stu = {
name: "张三",
age: 23,
play: function() {
console.log("打篮球");
console.log(this);
}
};
setInterval(stu.play, 1000); // this指的是window
// 3.
var obj = {
name: "lisi",
age: 23
};
setInterval(function() {
console.log(123);
console.log(this);
}, 1000); // this指的是window
// 1. 使用Math.max求数组中的最大值
var arr=[1,2,34,21,25,11];
var max=Math.max.apply(null,arr);
console.log(max);
function numMax(arr) {
return Math.max.apply(null, arr)
}
console.log(numMax([12, 24, 48, 36, 95, 43, 14]));
// 2. 对伪数组 var Jarr = {
// 0 : 13,
// 1 : 16,
// 2 : 56,
// 3 : 45,
// 4 : 19,
// length : 5
// }
// 使用数组的sort方法从大到小排序(修改 Array.prototype.sort方法的指向)
function sortNumb(a,b){
return b-a;
}
var Jarr = {
0 : 13,
1 : 16,
2 : 56,
3 : 45,
4 : 19,
length : 5
}
console.log(Array.prototype.sort.call(Jarr,sortNumb));
console.log(Array.prototype.sort.apply(Jarr,[sortNumb]));
// 3. 将伪数组 var Jarr = {
// 0 : 13,
// 1 : 16,
// 2 : 56,
// 3 : 45,
// 4 : 19,
// length : 5
// }
// 变成真数组(可以调用数组的一系列方法 : push, shift, concat, slice)
var Jarr = {
0 : 13,
1 : 16,
2 : 56,
3 : 45,
4 : 19,
length : 5
}
var arr=[];
arr=Array.prototype.slice.call(Jarr);
arr.push(56);
console.log(arr);