this
- 在对象内部的方法中使用对象内部的属性是一个非常普遍的需求。但JS的作用域机制并不支持这一点,为此,JS高出了this机制。
- this 和作用域链是2套不同的系统。
- 什么是this?
- this是和执行上下文绑定的, 每个执行上下文中都有一个this。
- 分三种类型:全局执行上下文中的this,函数中的this,eval中的this。
- 全局执行上下文中的this是指向window对象的,这是this合作用域链唯一的交点,作用域链的最底端包含了window对象,全局执行上下文中的this也是指向window对象。
- 函数执行上下文中的this:默认情况下调用一个函数,其执行上下文也是指向window对象。
- this 永远指向最后调用它的那个对象。
- 设置this指向方法
- 使用箭头函数:箭头函数的this始终指向函数定义时的this,而非指向时。箭头函数没有this绑定,必须通过查找作用域链来决定值,如果箭头函数被非箭头函数包含,则this绑定的时最近一层非箭头函数的this,否者,this为undefined。
- 在函数内部使用_this=this:将被调用的函数对象保存到变量_this变量中。
- 使用call、apply、bind改变this的指向。
/*
call()方法调有一个指定得this值和一个参数列表,参数1:thisArg可选。参数2:arg,arg2...返回值:使用调用者提 供的this值和参数调用该函数的返回值。
*/
Function.prototype.defineCall=function(ctx,...args){
if(!ctx){
ctx= typeof window !=='undefined'?window:global
}
ctx = Object(ctx)
const fnName = Symbol()
ctx[fnName] = this
const result = ctx[fnName](...args)
delete ctx[fnName]
return result
}
let fn = function(name,sex){
console.log(this,name,sex)
}
fn.call('','测试1') // window 测试1
fn.call({name:'测试1',sex:'boy'},'测试2') // {name:'测试1',sex:'boy'}
/*
apply()方法调用一个具有给定的this值得函数,以及一个参数数组。参数1:thisArg必选,参数2:argsArray可选
返回值:调用有this值和参数得函数得结果。
*/
Function.prototype.defineApply = function(ctx,args){
if(!ctx){
ctx = typeof window !== 'undefined'?window:global
}
ctx =Object(ctx)
const fnName = Symbol()
ctx[fnName]= this
// 将args参数数组,展开为多个参数,供函数调用
const result = ctx[fnName](...args)
delete ctx[fnName]
return result
}
let fn = function(name,sex){
console.log(this,name,sex)
}
fn.defineApply('',['测试2','boy']) // window 测试2 boy
fn.defineApply({name:'测试2',sex:'boy'},['测试2','boy']) // {name:'测试1',sex:'boy'} ['测试2','boy']
/*
bind()方法创建一个新的函数,在bind被调用时,这个新函数的this被指定为bind第一个参数,而其余参数作为新函数的参数,供调用时借用。
*/
Function.prototype.defineBind= function (context, ...args) {
const fn = this
args = args ? args : []
return function newFn(...newFnArgs) {
if (this instanceof newFn) {
return new fn(...args, ...newFnArgs)
}
return fn.apply(context, [...args,...newFnArgs])
}
}
const module = {
x: 42,
getX: function() {
return this.x;
}
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // undefined
const boundGetX = unboundGetX.defineBind(module);
console.log(boundGetX()) // 42
- 通过对象调用的方法设置:使用对象来调用其内部的一个方法,该方法的this是指向对象的。
- 通过构造函数设置
function CreateTest(){
this.name='测似1'
}
var testName = new CreateTest()