剛接觸js不久時對this總是感到無比迷茫,以下是來自js設計模式與實踐里的總結
this總是指向一個對象,有時指向全局對象,有時指向構造對象,有時指向DOM對象
1. 作為對象的方法調用
做為對象的方法調用時 this
指向對象本生
var Person = {
name: 'bingxl',
getName: function () {
console.log(this.name); //bingxl
}
};
Person.getName();
2. 作為普通函數被調用
普通函數里的this總是指向全局變量
var name = 'window';
function getName() {
var name = 'function';
return this.name;
}
console.log( getName()); //window 嚴格模式下為undefined
對象的方法復制給變量,在通過變量來調用后對象的方法變成了普通函數
var name = 'window';
var Person = {
name: 'bingxl',
getName: function () {
return this.name;
}
};
var getName1 = Person.getName;
console.log(getName1()); // window
var getName2 = Person.getName();
console.log(getName2); // bingxl
觀看這個例子發現:
getName1 = Person.getName 是把getName1指向Person.getName方法的內存地址(方法本身沒有被執行),其本質是個函數,所以在使用getName1() 時就是調用普通函數
getName2 = Person.getName() 是把Person.getName的返回值(已經執行了)bingxl賦值給getName2
對兩個變量經行typeof操作
console.log(typeof getName1); //function
console.log(typeof getName2);// string
3. DOM事件觸發函數里的this
DOM事件觸發函數里的this指向DOM節點本身
<!DOCHTML html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div id='person'>click this</div>
<script>
window.id = 'window';
var div = document.getElementById('person');
div.addEventListener('click', function () {
console.log(this.id); //person
var test = function () {
console.log(this.id); // window
};
test();
});
</script>
</body>
</html>
test() 是一個普通函數,所以test里的this指向了全局對象window
4. 構造器調用
使用new運算符調用構造函數時會返回一個對象,構造函數里的this一般就指向返回的對象
當構造函數使用return顯式的返回一個對象時new操作符返回的就是顯式返回的對象
var Person = function () {
this.name = 'bingxl';
};
var student = new Person();
console.log(student.name); // bingxl
var Person = function () {
this.name = 'bingxl';
return {
name: 'test'
};
};
var student = new Person();
console.log(student.name); // test
5. call , apply 和 bind
通過call 或apply調用會改變this的指向傳入的對象
var Doctor = {
name: 'bingxl',
profession: 'doctor',
getProfession: function () {
console.log(this.profession);
}
};
var Student = {
name: 'zhangsan',
profession: 'student'
};
Doctor.getProfession(); // doctor
Doctor.getProfession.call(Student); //student
6. 箭頭函數中的this
箭頭函數中的this就是定義時所在的this, 也就是說 箭頭函數本身沒有this。
箭頭函數也可以使用bind, call , applay來改變this指向
var env = 'window'
function Test() {
this.env = 'test function';
console.log('in Test Object', this.env); // test function
let arrow = () => {
console.log('in arrow function', this.env); // test function
};
arrow();
sub();
function sub( ) {
console.log('in sub ', this.env); // window, 普通函數中的this指向全局變量
}
}
const test = new Test();
對比 arrow 和 sub 函數可以看出
end