如下若是没说起,则为严格模式。
js中做用域有两种:python
词法做用域指在书写代码时就被肯定的做用域。
看以下代码babel
var value = 1; function foo() { console.log(value); } function bar() { var value = 2; foo(); } bar();// 结果是1
动态做用域指在代码运行时才被肯定的做用域。
js中只有this的做用域是动态做用域app
初学js时,会想固然认为this遵循某一条规律,就像物理学那样,然而并非。
this的绑定分为五种状况,这五种状况之间毫无规律可言。不过好在都很简单。框架
当以以下形式执行一个函数时,this为默认绑定;async
func()
与函数调用嵌套多少层如何嵌套无关函数
/* 全是undefined */ function printThis(){ return this } var obj = { say(){ console.log('obj.say',printThis()) } } function funcB(){ console.log('funcB',printThis()); obj.say(); } console.log('funcA',printThis()) obj.say() funcB()
当以以下行驶执行一个函数时,this为隐式绑定;工具
a.b.func()
此时this指向点前面一个对象this
class T { dotInvoke() { console.log('dotInvoke', this.sayThis()) } sayThis() { return this } assignInvoke() { var sayThis = this.sayThis; console.log('assignInvoke', sayThis()) } } var tt = new T(); tt.dotInvoke()// 指向T tt.assignInvoke()// undefined
function printThis(){ return this } var obj = {}; obj.say = printThis; obj.say()/* 指向obj */
极为常见的是回调函数的this是undefined,由于回调函数被复制给参数,参数再调用时变成了默认绑定翻译
function asyncFun(cb){ cb() } var obj = { callback(){ console.log(this) } } obj.callback()/*隐式绑定 obj */ asyncFun(obj.callback);/*默认绑定 undefined */
箭头函数会让this指向最近的函数或全局做用域code
function foo() { // 返回一个箭头函数 return (a)=>{ //this 继承自 foo() return this.a } ; } var obj1 = { a: 'obj1' }; var obj2 = { a: 'obj2' } var arrow1 = foo.call(obj1); var arrow2 = foo.call(obj2); var arrow3 = foo(); console.log('arrow1',arrow1())/* obj1 */ console.log('arrow2',arrow2())/* obj2 */ console.log('arrow3',arrow3())/* undefined,严格模式下报错 */
var printThis = ()=>this; console.log('printThis',printThis());/* global */
class Test { printThis = ()=>{ return this } } //会被babel翻译成 var test = function test() { var _this = this; this.printThis = function () { return _this; }; };
call, apply, bind指定this指向
构造函数,ES6中的class
new构造函数,new class时,this指向实例