作用域
作用域分为局部作用域和全局作用域,作用域往往和变量存在关系。处在局部作用域里面可以访问全局作用域的变量,而处在局部作用域外面不能访问局部作用域里面的变量。
看一个局部作用域访问全局作用域的例子
// 局部作用域访问全局作用域
let globalVariable="这是一个全局变量"
function globalFunction() {
let localVariable = '这是一个本地变量';
console.log(globalVariable); // 这是一个全局变量
console.log(localVariable); // 这是一个本地变量
}
globalFunction();
再试试全局作用域访问局部作用域
let globalVariable="这是一个全局变量"
function globalFunction() {
let localVariable = '这是一个本地变量';
console.log(globalVariable); // 这是一个全局变量
console.log(localVariable); // 这是一个本地变量
}
// 访问localVariable变量
console.log(localVariable)
globalFunction();
发现直接报错localVariable is not defined
把let提升成var试试
let globalVariable="这是一个全局变量"
function globalFunction() {
var localVariable = '这是一个本地变量';
console.log(globalVariable); // 这是一个全局变量
console.log(localVariable); // 这是一个本地变量
}
// 访问localVariable变量
console.log(localVariable)
globalFunction();
结果还是一样
上下文
上下文常常代表this变量的值以及它的指向,它决定一个函数怎么被调用,当一个函数被作为一个对象的方法调用时,this总是指向调用方法的对象。
非箭头函数
let pet = {
words: '...',
speak: function(){
console.log(this.words); //'...' 相当于pet.words
console.log(this === pet); // true
}
}
// pet 对象调用speak方法 那么this就是pet对象
pet.speak();
此时的this指向运行环境的顶层的global对象
function pet(words){
this.words = words;
console.log(words); //'...'
console.log(this === pet) //false
console.log(this === global) //true
}
pet('...');
console.log(global.words)
此时的this指向new出来的对象
function Pet(words){
this.words = words;
this.speak = function(){
console.log(this.words); //miao
console.log(this); //打印出当前对象{words:'miao',speak:[Function]}
}
}
var cat = new Pet('miao');
cat.speak();
箭头函数
引入箭头函数=>后,this不是指向函数调用的对象, 而是其父级对象
function globalFun() {
global.words = 'global';
let pet = {
words: '...',
speak: () => {
console.log(this.words); //'global'
console.log(this === global); // true
}
}
pet.speak();
}
globalFun()
call和apply
使用call和apply可以改变上下文执行对象,可以在自定义上下文中执行函数,两者作用相同,仅仅是方法的第二个参数不同,call直接使用参数列表,apply使用参数数组。具体作用是调用一个对象的方法,以另一个对象替换当前对象,实际上改变this指向的对象内容。
call
let cat = {
words: "miao",
speak: function (say) {
console.log(say + ' ' + this.words); // Speak wang
}
}
let dog = {
words: "wang",
}
cat.speak.call(dog,"Speak")
dog对象本来没有speak方法,通过call的方法,偷梁换柱地将原本指向pet的this变量指向了dog,因此在运行时,this.words=‘wang’,所以打印出Speak wang。通过这种方式,我们可以使一个对象去使用另一个对象的方法,一个容易想到的应用场景就是继承。
apply
使用方式和call 没什么区别,call直接使用参数列表,apply使用参数数组
let cat = {
words: "miao",
speak: function (say) {
console.log(say + ' ' + this.words); // Speak wang
}
}
let dog = {
words: "wang",
}
cat.speak.apply(dog,["Speak"])
参考文章 链接: 芒果屋里的猫 nodejs中call和apply的学习