四川建设厅网站 蒋免费收录平台
this指向
在运行时绑定,所以this和函数的调用方式和调用的位置有关,和定义的位置没关系
绑定规则
-
默认绑定(非严格模式下this指向全局变量,在严格模式下函数内的this指向undefined)
-
独立函数调用,没有主题
function foo(){console.log(this) } foo() //this指向window
-
-
隐式绑定
-
obj.method(),就是由一个对象调用的方法
var obj = {name:'11',foo:function(){console.log(this)} } obj.foo() //输出的this为{ name: '11', foo: [Function: foo] }
-
隐式丢失问题:在特定情况下会丢失绑定的对象
- 使用另一个变量来给函数取别名
- 将函数作为参数传递时会被隐式复制,回调函数丢失this绑定
-
-
显示绑定
-
call,apply,bind可以直接指定this的绑定对象,三者第一个参数都是this要指向的对象,若该参数是null或undefined,this则默认指向全局window
-
call和apply都是立即执行的,它们的的区别
//传参有区别 function sum(num1,num2) {console.log(num1+num2,this) }sum.call("call",20,30) sum.apply("apply",[20,30]) //分别输出 50 [String: 'call'] 50 [String: 'apply']
-
bind绑定,传参可以多次传入,实现参数合并,bind返回绑定this之后的函数
-
-
new构造函数绑定,this指向新生成的对象
function Person(name,age){this.name = namethis.age = age } var person = new Person("Tom",20) console.log(person.name,person.age) //输出:Tom 20
this绑定的优先级
- 默认绑定优先级最低
- 显示绑定优先级高于隐式绑定
- new绑定的优先级高于隐式绑定
- new绑定的优先级高于bind绑定(new不能和apply,call一起使用)
内置函数的this绑定
setTimeout(function(){console.log(this);//window
},2000)
箭头函数
箭头函数是es6新特性,不会绑定this和arguments属性,不能作为构造函数使用
根据外层作用域来决定this(不受this绑定的优先级影响)
有关this的面试题
https://juejin.cn/post/6844904083707396109
个人认为比较容易出错的几道面试题:
"use strict";
var a = 10;
function foo () {console.log('this1', this)console.log(window.a)console.log(this.a)
}
console.log(window.foo)
console.log('this2', this)
foo();//输出如下
f foo() {...}
'this2' Window{...}
'this1' undefined //为什么是undefined,因为在严格模式下,函数内的this指向是undefined
10
Uncaught TypeError: Cannot read property 'a' of undefined
let a = 10
const b = 20function foo () {console.log(this.a)console.log(this.b)
}
foo();
console.log(window.a)//输出如下
//let和const在全局定义变量不会挂载到window对象上,所以window访问不了这些变量
undefined
undefined
undefined
//隐式绑定的隐式丢失问题
//情况一
function foo () {console.log(this.a)
};
var obj = { a: 1, foo };
var a = 2;
var foo2 = obj.foo;obj.foo();
foo2();//输出如下
1
2 //为什么这里输出的是2,其实最简单的判断还是按照this的绑定规则,foo2()是符合默认绑定的,所以this指向的是window//情况二
function foo () {console.log(this.a) // 2,当一个函数被作为参数传递的时候,会发生隐式丢失问题,会把该函数的this绑定到window上
}
function doFoo (fn) {console.log(this) //{ a: 3, doFoo }fn()
}
var obj = { a: 1, foo }
var a = 2
var obj2 = { a: 3, doFoo }obj2.doFoo(obj.foo)
var name = 'window'
function Person (name) {this.name = namethis.obj = {name: 'obj',foo1: function () {return function () {console.log(this.name)}},foo2: function () {return () => {console.log(this.name)}}}
}
var person1 = new Person('person1')
var person2 = new Person('person2')person1.obj.foo1()() // 'window'
person1.obj.foo1.call(person2)() // 'window'
person1.obj.foo1().call(person2) // 'person2'person1.obj.foo2()() // 'obj'
person1.obj.foo2.call(person2)() // 'person2'
person1.obj.foo2().call(person2) // 'obj'