//this的指向共有5种类型
/**
* 作为对象的属性被调用 this指向该对象
*/
let obj = {
name: 'obj-Bob',
getName: function () {
return this.name
}
}
console.log(obj.getName()); //Bob
/**
* 作为普通函数被调用 this总是指向全局对象 通常为window
* 在严格模式下 this指向undefined
*/
var windowName = 'window-Bob' // var实际是定义到window对象
function functionGetName() {
console.log(this.windowName)
}
functionGetName();
/**
* 作为构造器调用 通常情况下 this指向被构造函数返回的实例
* 例外:如果构造函数显示的返回了一个object类型的对象 那么结果只会得到这个对象
*/
let myNameClass = function () {
this.name = 'constuctName'
}
let constructObj = new myNameClass()
console.log(constructObj.name);
/**
* 显式的返回了一个object对象 new出的对象最终会返回这个对象
* 只要构造器不显示的返回任何数据 或者返回非对象类型的数据,就不会出现这种情况
*/
let testMyNameClass = function () {
this.name = 'testMyclassName'
return {
name: 2
}
}
let returnObjNameClass = new testMyNameClass()
console.log(returnObjNameClass);
/**
* call或apply调用 可以动态改变函数的this
*/
let obj1 = {
name: 'obj1Name',
getName: function (number) {
return this.name + number
}
}
let obj2 = {
name: 'obj2Name'
}
// 相当于在obj2的作用域下调用obj1的getName()方法
console.log('null', obj1.getName(2))
console.log('call', obj1.getName.call(obj2, 2))
console.log('apply', obj1.getName.apply(obj2, [2]))
/**
* 箭头函数不会创建自己的this 从自己的作用域链的上一层继承this
*/
var val = 2;
let thisObj = {
val: 1,
getVal: () => {
return this.val
}
}
console.log('this', thisObj.getVal());
//情况一
let type1 = {
name: '1',
getName: function () {
return this.name
}
}
console.log('type1', type1.getName());
//将对象里的方法赋给getName2
let getName2 = type1.getName;
// 作为普通函数被调用 this指向全局对象
console.log('type1-window', getName2());
/**
* call和apply的用处
* 1调用构造函数实现继承
*/
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price, food) {
Product.call(this, name, price); //
this.category = food;
}
var hotDog = new Food('hotDog', 20);
/**
* call和apply的用处
* 2调用函数并指定上下文this
*/
function showName() {
console.log(this.id + ':' + this.name);
};
var useCallObj = {
id: 1,
name: 'yuguang'
};
showName.call(obj)
/**
* call和apply的用处
* 3单纯调用函数
*/
Math.max.apply(null, [1, 2, 3, 10, 4, 5]);
/**
* bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用
*/
var name = 'window'
var person1 = {
name: 'person1',
show1: function () {
console.log(this.name)
},
show2: () => console.log(this.name),
show3: function () {
return function () {
console.log(this.name)
}
},
show4: function () {
return () => console.log(this.name)
}
}
var person2 = { name: 'person2' }
person1.show1() //person1
person1.show1.call(person2) //person2
person1.show2() //window
person1.show2.call(person2) //window
person1.show3()() //window
person1.show3().call(person2) //person2
person1.show3.call(person2)() //window
person1.show4()() //person1
person1.show4().call(person2) //person1
person1.show4.call(person2)() //person2
// 模拟call
var value = '111';
function show(a, b) {
console.log(this.value);
console.log(a, b)
}
// show();
Function.prototype.setCall = function (obj) {
//判断是否传参,
let setCallObj = obj || window
// this为使用函数 并赋给传参对象
setCallObj.func = this
//获取参数
let list = [];
for (let index = 1; index < arguments.length; index++) {
list.push(arguments[index])
}
//执行函数
eval(`setCallObj.func(${list})`)
//删除刚才赋给传参对象的函数
delete setCallObj.func
}
var foo = {
value: '222'
}
show.setCall(foo, 1, 2);
this指向详解
最新推荐文章于 2024-05-30 11:21:03 发布