目录
谈谈你对this的理解?
this指向问题
this,指向的是函数调用者,不同情况下它的指向不同。
- 函数调用模式 fn() 指向window的情况 ( 默认绑定)
- 方法调用模式 obj.fn() 谁调用, this指向谁,( 隐式绑定)
- 上下文调用模式 , 想让this指向谁, this就指向谁, (显式绑定,又叫做硬绑定 call()、 apply() 、 bind())
function Person(userName) {
this.userName = userName; //构造函数中的this指向实例对象person
}
var person = new Person("lisi");
console.log(person.userName); //lisi
var a = 10;
var obj = {
a: 120,
method: function () {
var bar = function () {
console.log(this.a); //10 window调用
};
bar();
return this.a;
},
};
console.log(obj.method()); // 120 对象调用
var num = 10;
function Person() {
num = 20;
this.num = 30;
}
Person.prototype.getNum = function () {
return this.num;
};
var person = new Person();
console.log(person.getNum()); //30 对象调用
var fullName = "language";
var obj = {
fullName: "javascript",
prop: {
getFullName: function () {
return this.fullName;
},
},
};
console.log(obj.prop.getFullName()); // undefined obj.prop调用
var test = obj.prop.getFullName; // language
console.log(test());//window调用
var val = 1;
var json = {
val: 10,
dbl: function () {
//val *= 2; 1*2=2
this.val *= 2; //10*2=20
},
};
json.dbl();
//console.log(json.val + val) 10+2=12
console.log(json.val + val) //21
var num = 10;
var obj = { num: 20 };
obj.fn = (function (num) {
this.num = num * 3; // this.num = 60 //this window
num++; // 21
return function (n) {
this.num += n; // 65 30 //this obj
num++; // 22 23
console.log(num); // 22 23
};
})(obj.num);
var fn = obj.fn;
fn(5);
obj.fn(10);
console.log(num, obj.num); // 65 30
var value = 10;
var obj = {
value: 20,
};
var method = function () {
console.log(this.value);
};
method(); // 10
method.call(obj); // 20
method.apply(obj); // 20
var newMethod = method.bind(obj);
newMethod(); // 20
var userInfo = {
data: [
{ userName: "zhangsan", age: 20 },
{ userName: "lisi", age: 21 },
],
getUserInfo: function () {
var index = 1;
console.log(this.data[index].userName + " "+ this.data[index].age);
},
};
var btn = document.getElementById("btn");
//btn.onclick = userInfo.getUserInfo; //this指向btn按钮,函数里的this就指向window,window里没有data属性
btn.onclick = userInfo.getUserInfo.bind(userInfo);
//将this强制指向userInfo,便可获取到数据
var userInfo = {
data: [
{ userName: "zhangsan", age: 20 },
{ userName: "lisi", age: 21 },
],
getUserInfo: function () {
//方法一:
// var that = this;
// this.data.forEach(function (p) {
// console.log(that); 指向对象
// });
//方法二:
//this.data.forEach((p) => {
// console.log(this); 指向userInfor
// });
this.data.forEach(function (p){ //this指向userInfo
console.log(this); //this指向window,闭包环境中,this关键字无法访问或获取到外部函数的this变量
});
},
};
var btn = document.getElementById("btn");
btn.onclick = userInfo.getUserInfo.bind(userInfo);
改变this指向的三种方法
硬绑定 => call apply bind
function add(a, b) {
console.log(this);
console.log(a + b);
}
function sub(a, b) {
console.log(a - b);
}
// add.call(sub, 3, 6); this指向sub
// add.apply(sub, [3, 5]); this指向sub,以数组的形式传参,有隐含作用,可将数组转换为列表
var newFn = add.bind(sub, 3, 3);
newFn(); //this指向sub,返回的是新的函数,随时调用
应用场景1
区别:
call()和apply()
会立即执行所调用的函数,参数的传递方式不同,apply以数组的形式传参,
bind()
返回的是新的函数,随时调用
//1. 求数组中的最大值和最小值
var arr = [3, 6, 2, 8, 9, 10];
console.log(Math.max.apply(null, arr));
console.log(Math.min.apply(null, arr));
//2.将arguments转换为真正的数组
function fn() {
var arr = Array.prototype.slice.call(arguments);
arr.push(6);
return arr;
}
console.log(fn(1, 2));
应用场景2
//实现继承
function Person(userName, userAge) {
this.userName = userName;
this.userAge = userAge;
}
function Student(name, age, gender) {
Person.call(this, name, age);//Person.call完成对Person函数的调用,this代表Student这个构造函数创建出来的对象student
this.gender = gender;
}
var student = new Student("zhangsan", 20, "男");
console.log(
"userName=" +
student.userName +
",userAge=" +
student.userAge +
",gender=" +
student.gender)
//改变匿名函数this的指向
var person = [
{ id: 1, userName: "zhangsan" },
{ id: 2, userName: "lisi" },
];
for (var i = 0; i < person.length; i++) {
(function (i) {
this.print = function () { //this指向window
console.log(this.id);
};
this.print();
}.call(person[i], i)); //改变匿名函数this指向person中的每个对象
}
手动实现call函数
Function.prototype.myCall = function (context) { //自己定义的函数放到原型对象上,方便后续调用,参数context代表this的指向
var args = [...arguments].slice(1);
context = context || window;
context.fn = this; // Sub.fn=Add context添加一个属性fn,this指向Add
var result = context.fn(...args); // Sub.fn(6,3)
return result;
};
function Add(num1, num2) {
console.log(this); //this指向sub
console.log(num1 + num2);
}
function Sub(num1, num2) {
console.log(num1 - num2);
}
Add.myCall(Sub, 6, 3);
标签:function,console,log,指向,谈谈,理解,var,obj
From: https://www.cnblogs.com/xiayuxue/p/16614268.html