JavaScript中this关键字的定义:
this是JavaScript语言中的一个关键字 它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用
普通函数/对象/构造函数里的函数的定义及其对应的调用方式
- 普通函数里函数的定义和调用
function fn(){
let name = "John"
let age = 18
function say(){
console.log(this)
}
say() / return say() 这两种写法都是在fn()里面调用say()
}
fn() // window
或
function fn(){
let name = "John"
let age = 18
return ()=>{
console.log(this)
}
}
fn()() // window
复制代码
- 构造函数里函数的定义和调用
function Person(name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(this);
}
}
var p = new Person("John",18)
p.say() // Person {name: "John", age: 18, say: ƒ}
复制代码
- 对象里函数的定义和调用
var obj = {
name: "John",
age: 18,
say: function () {
console.log(this)
}
}
obj.say() // {name: "John", age: 18, say: ƒ}
或
var obj = {}
obj.name = "John"
obj.age = 18
obj.say = function () {
console.log(this)
}
obj.say() // {name: "John", age: 18, say: ƒ}
复制代码
判断this的指向(隐式绑定、window绑定)
this的指向,始终坚持一个原理:this永远指向最后调用它的那个对象。
这个对象怎么判断,如果有.
就是.
前面的,如果没有则下默认是window
隐式绑定(有.
的)
var name = "windowsName";
var a = {
name: "Cherry",
fn : function () {
console.log(this.name);
}
}
a.fn(); // Cherry
window.a.fn(); // Cherry
复制代码
window绑定(没有.
的)
var name = "windowsName";
var a = {
name: "Cherry",
fn : function () {
console.log(this.name);
}
}
var f = a.fn;
f(); // windowsName
复制代码
箭头函数的this指向
记住一句话:如果箭头函数被普通函数包含(注意不是obj),则this指向跟着最近一层普通函数指向;如果没有被普通函数包含,则箭头函数的this指向window
let obj = {
a: 2,
c: {
a: 3,
d: () => {
console.log(this);
console.log(this.a);
}
}
}
obj.c.d(); // window, undefined
复制代码
setTimeout里的this指向
- 如果setTimeout里面是普通函数形式,则this永远指向window
- 如果setTimeout里面是箭头函数形式,则this就跟着最近一层普通函数的this指向
改变this的指向
改变this指向有两种方法:
把this用一个变量存起来
这里原本setTimeout里面的普通函数的this会指向window,而我们需要其指向F()
var num = 0;
function F (){
var that = this; //将this存为一个变量,此时的this指向f
this.num = 1,
this.getNum = function(){
console.log(this.num);
},
this.getNumLater = function(){
setTimeout(function(){
console.log(that.num); //利用闭包访问that,that是一个指向obj的指针
}, 1000)
}
}
var f = new F();
f.getNum();//1 打印的是obj.num,值为1
f.getNumLater()//1 打印的是obj.num,值为1
复制代码
显式绑定(call/apply/bind)
这里greet()函数和user对象是分开的,没有任何包含关系,怎么让greet()能够访问到user里的name呢
function greet (person1, person2, person3) {
console.log(`Hello, my name is ${this.name} and I know ${person1}, ${person2}, and ${person3}`)
}
const user = {
name: 'Tyler',
age: 27,
}
const people = ['John', 'Ruby', 'Deck']
复制代码
call()方法
函数.call(对象/函数,参数1,参数2,参数3,…)
greet(user,people[0],people[1],people[2])
// Hello, my name is Tyler and I know John, Ruby, and Deck
复制代码
这样需要将数组的一个一个元素一个个写入显得太麻烦了,于是我们引入apply()方法
apply()方法
函数.apply(对象/函数,[数组])
greet(user,people)
// Hello, my name is Tyler and I know John, Ruby, and Deck
复制代码
bind()方法
函数.bind(对象/函数,参数1,参数2,参数3,…)
参考文章
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END