this指向详解

//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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值