网站设计 珠海,南浔做网站,search搜索引擎,代运营this 的值取决于它出现的上下文#xff1a;函数、类或全局。
在函数内部#xff0c;this 的值取决于函数如何被调用#xff0c;this 是语言在函数体被执行时为你创建的绑定
对于典型的函数#xff0c;this 的值是函数被访问的对象。换句话说#xff0c;如果函数调用的形…this 的值取决于它出现的上下文函数、类或全局。
在函数内部this 的值取决于函数如何被调用this 是语言在函数体被执行时为你创建的绑定
对于典型的函数this 的值是函数被访问的对象。换句话说如果函数调用的形式是 obj.f()那么 this 就指向 obj例如
function getThis() {return this;
}const obj1 { name: obj1 };
const obj2 { name: obj2 };obj1.getThis getThis;
obj2.getThis getThis;console.log(obj1.getThis()); // { name: obj1, getThis: [Function: getThis] }
console.log(obj2.getThis()); // { name: obj2, getThis: [Function: getThis] } 注意虽然函数是相同的但是根据其调用的方式this 的值是不同的。这与函数参数的工作方式类似。 this到底指向谁 调用函数会创建新的属于函数自身的执行上下文执行上下文的调用创建阶段会决定this的指向结论this的指向是在调用函数时根据执行上下文所动态确定的或者说this关键字指向函数方法运行时的所有者 1.规则 在函数体中简单调用该函数时非显式/隐式绑定下严格模式下this绑定到undefined否则绑定到全局对象window/global一般构造函数new调用绑定到新创建的对象上一般由call/bind/apply方法显式调用绑定到指定参数的对象上一般由上下文对象调用绑定在该对象上箭头函数中根据外层上下文绑定的this决定this的指向 2.实例分析练习
1全局环境下的this
function f1(){console.log(this);
}function f2() {use strictconsole.log(this);
}f1() //Window对象
f2() //undefined
const foo {bar: 10,fn: function () {console.log(this); //Windowconsole.log(this.bar); //undefined}
}var fn1foo.fn
fn1()
上题中this指向的是window虽然fn函数在foo对象中作为方法被引用但是在赋值给fn1后fn1的执行仍然是在window的全局环境中
const foo {bar: 10,fn: function () {console.log(this); //{bar:10,fn:f}console.log(this.bar); //10}
}foo.fn()
上题中this指向的是最后调用他的对象在foo.fn()语句中this指向foo对象 注意在执行函数时如果函数中的this是被上一级的对象所调用那么this指向的就是上一级的对象否则指向全局环境 2上下文对象调用中的this
const student{name:hist,fn:function(){return this}
}console.log(student.fn()student); //true
const person {name: hist,brother: {name: comp,fn: function () {return this.name}}
}console.log(person.brother.fn()); //comp
上题在这种嵌套关系中this指向最后调用它的对象
const o1 {text: o1,fn: function () {return this.text}
}const o2 {text: o2,fn: function () {return o1.fn()}
}const o3 {text: o3,fn: function () {var fn o1.fnreturn fn()}
}console.log(o1.fn()); //o1
console.log(o2.fn()); //o1
console.log(o3.fn()); //undefined
第二个相当于最后调用时还是用o1调用的fn()
第三个将o1.fn()赋值给fn后直接调用fn()没有用对象点调用所以这里this指向window 如果想让第二个输出o2怎么做? const o2 {text: o2,fn: o1.fn()
} 此时我们将赋值操作提前相当于先把o1.fn()变为this.text此时我们用o2调用fn()指向的就是o2对象 3bind/call/apply改变this指向 补充bind/call/apply使用方法 const target{}fn.call(target, arg1, arg2)
fn.apply(target,[arg1,arg2])
fn.bind(target, arg1, arg2)() 示例一
function greet() {console.log(Hello, ${this.name});
}const person { name: Alice };// 使用 call 明确指定 this
greet.call(person); // 输出Hello, Alice示例二
function greet(city, country) {console.log(Hello, ${this.name} from ${city}, ${country});
}const person { name: Bob };// 使用 apply参数是数组
greet.apply(person, [New York, USA]); // 输出Hello, Bob from New York, USA示例三
function greet() {console.log(Hello, ${this.name});
}const person { name: Charlie };// 使用 bind 创建一个新的函数
const boundGreet greet.bind(person)();// 输出Hello, Charlie 4构造函数和this
function Foo(){this.barhist
}const instancenew Foo()
console.log(instance.bar);//hist new操作符调用构造函数做了什么 创建一个新的对象将构造函数的this指向这个新对象为这个对象添加属性、方法等最终返回新对象 下面是构造函数中出现显示return的情况分为两种场景
function Foo() {this.user histconst o {}return o
}const instance new Foo()
console.log(instance.user);//undefined 将会输出 undefined此时 instance 是返回的空对象 o。
function Foo() {this.user hist;return 1;
}const instance new Foo();
console.log(instance.user);//hist 将会输出 hist也就是说此时 instance 是返回的目标对象实例 this。 结论如果在构造函数中显式返回一个值且返回的是一个对象那么 this 就指向这个返回的对象如果返回的不是一个对象那么 this 仍然指向实例。 5箭头函数中的this指向 箭头函数和普通函数有一个重要的区别箭头函数不会有自己的 this它会继承外部上下文的 this。 const foo {fn: function () {setTimeout(function () {console.log(this);});},
};
foo.fn();//window
this 出现在 setTimeout() 中的匿名函数里因此 this 指向 window 对象
const foo {fn: function () {setTimeout(() {console.log(this);});},
};foo.fn();//{fn: ƒ}
在 foo.fn() 调用时this 在 fn 方法内指向 foo 对象。setTimeout 中的箭头函数继承了外部的 this也就是 foo 对象。
6this优先级 通过 call、apply、bind、new 对 this 绑定的情况称为显式绑定 根据调用关系确定的 this 指向称为隐式绑定 function foo(a) {console.log(this.a);
}const obj1 {a: 1,foo: foo,
};const obj2 {a: 2,foo: foo,
};obj1.foo.call(obj2); //2
obj2.foo.call(obj1); //1
call、apply 的显式绑定一般来说优先级更高
function foo(a) {this.a a;
}const obj1 {};
var bar foo.bind(obj1);
bar(2);
console.log(obj1.a);
上述代码通过 bind将 bar 函数中的 this 绑定为 obj1 对象。执行 bar(2) 后obj1.a 值为 2。即经过 bar(2) 执行后obj1 对象为{a: 2}。
当再使用 bar 作为构造函数时
var baz new bar(3)
console.log(baz.a)//3
将会输出 3。我们看 bar 函数本身是通过 bind 方法构造的函数其内部已经将 this 绑定为 obj1它再作为构造函数通过 new 调用时返回的实例已经与 obj1 解绑。 也就是说new 绑定修改了 bind 绑定中的 this因此 new 绑定的优先级比显式 bind 绑定更高。
function foo() {return (a) {console.log(this.a);};
}const obj1 {a: 1,
};const obj2 {a: 2,
};const bar foo.call(obj1);
bar.call(obj2);//1
由于 foo() 的 this 绑定到 obj1bar引用箭头函数的 this 也会绑定到 obj1箭头函数的绑定无法被修改。
var a 123;const foo () (a) {console.log(this.a);};const obj1 {a: 2,};const obj2 {a: 3,};const bar foo.call(obj1);console.log(bar.call(obj2));//123
箭头函数的绑定无法被修改foo的执行上下文是window 如果将第一处的var a 123;改为const a 123; 答案将会输出为 undefined原因是因为使用 const 声明的变量不会挂载到 window 全局对象当中