一、关于this
- 存在于函数的作用域中,可以是全局作用域,也可以是函数作用域中。
- this只是一个关键字,只有在它所处的函数被调用时,它才有实际意义。
- 在作用域链的知识点的时候,了解到。当函数被调用时,会创建一个对象(活动记录或者执行上下文)。这个对象包括了函数调用时传入的参数,函数的局部变量等等。this就是这个活动记录的一个属性,在函数执行的过程中会用到。
- 存在即合理。由于this的灵活性,函数里的this"隐式"地传递一个对象的引用,可以自动引用合适的上下文对象。
- 综上,this在函数调用时,会绑定一个对象,绑定的对象是什么取决于函数在哪里被调用。
二、this的绑定
- 箭头函数
let obj = {
a:"zoey"
}
function test_fn(){
console.log(`==外部函数this=this.b=${this.b}`);//undefined
this.b = "name" ;
console.log(`==外部函数this=this.a=${this.a}`);//zoey
let point_fn=()=>{
console.log(`==箭头函数=this.a===${this.a}`);//zoey
};
point_fn();
}
test_fn.apply(obj);
箭头函数的this就是外部代码块的this。它的this对象在函数定义时已经确定。
2.new 关键字
function Player(obj){
this.width = obj.w||1280;
this.height = obj.h||720;
}
let param_obj = {
w:1920,
height:1080,
}
let player = new Player(param_obj);
console.log(`==player.width==${player.width}`);//1920
new运算符调用的函数的this绑定新创建的实例对象,在这里是player。正是因为,this绑定了新建的player对象,使得player有width这个属性。
3.bind
function fnc_init(num){
console.log(`===this.a==${this.a}===num===${num}`);
return this.a + num;
}
let test_obj = {
a:7
};
let fnc = fnc_init.bind(test_obj);
let bar = fnc(6);//===this.a==7===num===6
console.log(`==bar==${bar}`)//==bar==13
bind()会返回一个新的函数fnc,bind函数会把参数test_obj设置为this的上下文,并调用原始函数。
4.apply和call
let obj_apply = {
a:"zoey"
}
let obj_call = {
b:"name"
}
function test_fn(){
console.log(`==this.a=${this.a}`);
}
test_fn.apply(obj_apply);//==this.a=zoey
this通过apply绑定到了obj_apply这个对象,获取到是:obj_apply.a
let obj_apply = {
a:"zoey"
}
let obj_call = {
b:"name"
}
function test_fn(){
//console.log(`==this.a=${this.a}`);
console.log(`==this.b=${this.b}`);//==this.b=name
}
//test_fn.apply(obj_apply);
test_fn.call(obj_call)
this通过call绑定到了obj_call这个对象,获取到是:obj_call.b
5.“隐式”绑定
let obj={
name:'zoey',
get_name:get_name
}
function get_name(){
console.log(`==getName==${this.name}`)
}
var name = "fool";
obj.get_name();//==getName==zoey
这里的this绑定到obj这个对象.
6.默认绑定
let obj={
name:'zoey',
get_name:get_name
}
function get_name(){
console.log(`==getName==${this.name}`)
}
var name = "fool";
get_name();//==getName==fool
默认绑定到window上。
补充:严格模式下
<script>
"use strict"
let obj={
name:'zoey',
get_name:get_name
}
function get_name(){
console.log(`==this==${this}`);//==this==undefined
console.log(`==getName==${this.name}`)
//TypeError: Cannot read property 'name' of undefined
}
var name = "fool";
get_name();
</script>
严格模式下会默认绑定到undefined
三、this的绑定按照以上1~6的优先级,依次递减。(如果还是比较迷惑,可以打开浏览器调试工具,在this处打断点,帮助分析)