话不多说,进入正题
本文内容有问题,请勿再观看!!!!!!!!!
this指向有四种模式:
- 默认绑定
- 隐式绑定
- 显式绑定
- new绑定
优先级:new > 显示绑定 > 隐式绑定 > 默认绑定
默认绑定
发生在没有适应绑定规则时的规则。 通常是独立函数调用。
所以他才叫做默认呢
例子:
let name = 'key'
function Hi(){
console.log('Hello,', this.name);
}
Hi();//Hello,key
在调用Hi()时,应用了默认绑定,this指向全局对象(全局上下文,浏览器中是window)。 在严格模式下,this指会向undefined,undefined上没有this对象,会抛出错误。
注意:node环境下也会指向undefined。
隐式绑定
当调用有(函数)上下文时 典型:foo.fun()
例子:
var name = 'another guy';
function Hi(){
console.log('Hello,', this.name);
}
var person = {
name: 'key',
sayHi: Hi
}
person.sayHi();//Hello,key
由于person调用了Hi(),所以隐式绑定把函数调用中的this绑定到了person身上。
注意,xxx.xxx.fn()之后最有一层会影响this指向,即this指向最深层调用对象。
隐式绑定的丢失问题
let name = 'another guy';
function Hi(){
console.log('Hello,', this.name);
}
let person = {
name: 'key',
sayHi: Hi
}
let foo = person.sayHi();
foo//Hello,key
在这个例子中,foo指向指向了Hi()的引用,与person无关。
显式绑定
即call
,apply
。
call和apply的作用一样,只是传参方式不同。call和apply都会执行对应的函数,而bind方法不会。
var a ={ name : "key", fn : function (a,b) { console.log( a + b,this.name) } } var b = a.fn; b.apply(a,[1,2]) // 3 key
var a ={ name : "key", fn : function (a,b) { console.log( a + b,this.name) } } var b = a.fn; b.call(a,1,2) // 3 key
var a ={ name : "key", fn : function (a,b) { console.log( a + b,this.name) } } var b = a.fn; b.bind(a,1,2)() // 3 key
var name = 'another guy';
function Hi(){
console.log('Hello,', this.name);
}
var person = {
name: 'key',
sayHi: Hi
}
var Hi = person.sayHi;
Hi.call(person); //Hello,key
显式绑定也会丢失
function sayHi(){
console.log('Hello,', this.name);
}
var person = {
name: 'key',
sayHi: sayHi
}
var name = 'anohter guy';
var Hi = function(fn) {
fn();
}
Hi.call(person, person.sayHi); //Hello,another guy
如何不丢失:
function sayHi(){
console.log('Hello,', this.name);
}
var person = {
name: 'key',
sayHi: sayHi
}
var name = 'anohter guy';
var Hi = function(fn) {
fn.call(this);
}
Hi.call(person, person.sayHi);//Hello,key
new
我们使用new来调用函数的时候,就会新对象的this就会绑定到这个函数上(或全局上下文)。
function setName(name){
this.name = name;
}
var Hi = new setName('key');
console.log('Hello,', Hi.name);//Hello,key
那么new又具体干了什么呢?
箭头函数
箭头函数没有自己的this、super、arguments和new.target绑定。
箭头函数中没有this绑定,也不就使用上述四种规则,必须通过查找作用域链来决定其值。
如果箭头函数被非箭头函数包含,则this绑定的是最近一层非箭头函数的this,否则this的值则被设置为全局对象。
var name = 'another guy';
var student = {
name: 'key',
doSth: function(){
// var self = this;
var arrowDoSth = () => {
// console.log(self.name);
console.log(this.name);
}
arrowDoSth();
},
arrowDoSth2: () => {
console.log(this.name);
}
}
student.doSth(); // 'key'
student.arrowDoSth2(); // 'another guy'