网站管理工作,公司做网站那家好,网站开发公司模版,餐饮平台app有哪些具体见#xff1a;https://github.com/febobo/web-interview 10.this指向
根据不同的使用场合#xff0c;this有不同的值#xff0c;主要分为下面几种情况#xff1a;
默认绑定隐式绑定new绑定显示绑定
①默认绑定
全局环境中定义person函数#xff0c;内部使用this关… 具体见https://github.com/febobo/web-interview 10.this指向
根据不同的使用场合this有不同的值主要分为下面几种情况
默认绑定隐式绑定new绑定显示绑定
①默认绑定
全局环境中定义person函数内部使用this关键字
var name Jenny;
function person() {return this.name;
}
console.log(person()); //Jenny上述代码输出Jenny原因是调用函数的对象在游览器中位window因此this指向window所以输出Jenny
注意
严格模式下不能将全局对象用于默认绑定this会绑定到undefined只有函数运行在非严格模式下默认绑定才能绑定到全局对象
②隐式绑定
函数还可以作为某个对象的方法调用这时this就指向这个上级对象。
//this 永远指向最后调用它的对象
var o {a:10,b:{fn:function(){console.log(this.a); //undefined}}
}
o.b.fn();因为this的上一级对象为b而b内部并没有a变量的定义所以输出undefind
③new绑定
通过构建函数new关键字生成一个实例对象此时this指向这个实例对象
function test() {this.x 1;
}var obj new test();
obj.x // 1上述代码之所以能过输出1是因为new关键字改变了this的指向。
而当new的过程中遇到return一个对象时此时this指向这个对象。
function fn()
{ this.user xxx; return {user 123};
}
var a new fn();
console.log(a.user); //123而当return一个基本类型时this还是指向它的实例。
function fn()
{ this.user xxx; return 1;
}
var a new fn;
console.log(a.user); //xxxnull同理指向实例。
④显式修改
使用apply | call | bind改变函数的调用对象第一个参数就是改变后调用这个函数的对象。
var x 0;
function test() {console.log(this.x);
}var obj {};
obj.x 1;
obj.m test;
obj.m.apply(obj) // 1而三者的区别
三者都可以改变函数的this对象指向三者第一个参数都是this要指向的对象如果如果没有这个参数或参数为undefined或null则默认指向全局window三者都可以传参但是apply是数组而call是参数列表且apply和call是一次性传入参数而bind可以分为多次传入。bind 是返回绑定this之后的函数apply 、call 则是立即执行 。
⑤箭头函数
箭头函数的this非常特殊因为它在函数定义时就被确定了而且不会被动态改变。
bodydivbutton classbtn1普通函数/buttonbutton classbtn2箭头函数/button/div
/bodyconst btn1 document.querySelector(.btn1);
const btn2 document.querySelector(.btn2);btn1Click function () {console.log(btn1 this); //button
}
btn2Click () {console.log(btn2 this); // window
}
btn1.addEventListener(click, btn1Click, false);
btn2.addEventListener(click, btn2Click, false);可以看到默认函数的是由btn2调用的所以指向btn2而箭头函数在编译时就被绑定了即btn2Click在创建时就定义了this所以this指向window对象。
此外箭头函数可以看作是匿名函数是一次性的所以与默认函数区别很明显。
箭头函数没有构造函数没有原型对象箭头函数没有arguments对象箭头函数的this在定义时就被确认了不会动态更新
其他
隐式绑定 VS 显式绑定
function foo() {console.log( this.a );
}var obj1 {a: 2,foo: foo
};var obj2 {a: 3,foo: foo
};obj1.foo(); // 2
obj2.foo(); // 3obj1.foo.call( obj2 ); // 3
obj2.foo.call( obj1 ); // 2显然显示绑定的优先级更高
new绑定 VS 隐式绑定
function foo(something) {this.a something;
}var obj1 {foo: foo
};var obj2 {};obj1.foo( 2 );
console.log( obj1.a ); // 2obj1.foo.call( obj2, 3 );
console.log( obj2.a ); // 3var bar new obj1.foo( 4 );
console.log( obj1.a ); // 2
console.log( bar.a ); // 4可以看到new绑定的优先级隐式绑定
new绑定 VS 显式绑定
因为new和apply、call无法一起使用但硬绑定也是显式绑定的一种可以替换测试
function foo(something) {this.a something;
}var obj1 {};var bar foo.bind( obj1 );
bar( 2 );
console.log( obj1.a ); // 2var baz new bar( 3 );
console.log( obj1.a ); // 2
console.log( baz.a ); // 3bar被绑定到obj1上但是new bar(3) 并没有像我们预计的那样把obj1.a修改为3。但是new修改了绑定调用bar()中的this
我们可认为new绑定优先级显式绑定
综上new绑定优先级 显示绑定优先级 隐式绑定优先级 默认绑定优先级