this 是甚麼
the object that is executing the current function.
rule of this
- if the function is part of an object, we called the function and method. Hence, if a function is a method of an object, this references the object itself.
- if the function is the regular function, which means it's not part of an object, this reference the global object which is window object in browsers and global in node.
// method -> object
// function -> global (window, global)
ex1
const video = {
title: 'a',
play() {
console.log(this)
}
}
video.stop = function() {
console.log(this)
}
video.play()
// play is a method in the video object
// "this" reference this object itself
video.stop()
// stope is the method in the video object
// again this reference this object itself
ex2
function playVideo() {
console.log(this)
}
playVideo()
// window in browsers and global in node
ex3
we call constructor functions using the new operator.
using new operator, this new operator creates a new empty object { } and set this in the constructor function to the { } object
function Video(title) {
this.title = title // add title property to the new object { }
console.log(this)
}
const v = new Video('a') // new 關鍵字創建一個 object { }
// get a new object => Video {title: "a"}
ex4
const video = {
title: 'a',
tags: ['a', 'b', 'c'],
showTags() {
this.tags.forEach(function(tag) {
console.log(tag)
})
}
}
video.showTags() // a b c
want to show title to each tags
this.title we get undefined
const video = {
title: 'a',
tags: ['a', 'b', 'c'],
showTags() {
this.tags.forEach(function(tag) {
console.log(this.title, tag)
})
}
}
video.showTags()
remove title property and see what change => we see the window object
since here we are inside the call back function, this function is just a regular function and it's not the method of the video object. the only method we have in video is showTags.
const video = {
title: 'a',
tags: ['a', 'b', 'c'],
showTags() {
this.tags.forEach(function(tag) {
console.log(this, tag) // this 在 regular function 裡面,所以他 reference 的是 global object,so it's the global object that is executing this callback function
})
}
}
video.showTags()
所以可以怎麼做達到目的 ?
forEach(cb, thisArg?) so we can pass an object here so this can reference this object.
const video = {
title: 'a',
tags: ['a', 'b', 'c'],
showTags() {
this.tags.forEach(function(tag) {
console.log(this, tag) // this is reference to {firstName: 'may'}
}, {firstName: 'may'})
}
}
video.showTags()
運用這樣的特性,我們在 forEach 的第二個參數傳入 this
const video = {
title: 'a',
tags: ['a', 'b', 'c'],
showTags() {
this.tags.forEach(function(tag) {
console.log(this, tag) // this is reference to video
}, this) // in the showTags method, so this reference to the current object. we still int the EC of the show tags method
}
}
video.showTags()
所以
const video = {
title: 'a',
tags: ['a', 'b', 'c'],
showTags() {
this.tags.forEach(function(tag) {
console.log(this.title, tag) // this is reference to video
}, this) // in the showTags method, so this reference to the current object. we still int the EC of the show tags method
}
}
video.showTags()