本文已参与「新人创作礼」活动,一起开启掘金创作之路
1、函数直接使用,this此时指向windows
function get(content) {
console.log(content);
}
get("你好"); // 你好
// 上面的是下面的语法糖
get.call(window, "你好"); // 你好
var people = "outPeople";
function hello() {
let people = "innnerPeople";
console.log("hello", this.people);
}
hello(); // hello outPeople
// 上面的是下面的语法糖
hello.call(window); // hello outPeople
2、函数作为对象的方法被调用,原则:谁调用我,this就指向谁
var person = {
name: "大明",
run: function (time) {
console.log(`${this.name}在跑步 最多${time}min就不行了`);
},
};
var student = {
name: "学生",
};
person.run(30); // 大明在跑步 最多30min就不行了
// 上面的是下面的语法糖
person.run.call(person, 30); // 大明在跑步 最多30min就不行了
// 原则:谁调用我,我就指向谁,person调用run(),则this指向person
// 改变调用函数的主体为student,student调用run(),则this指向student
person.run.call(student, 20); // 学生在跑步 最多20min就不行了
了解了上面两个特性,尝试做两道题练练手吧!
题目一:控制台打印出什么?
var name = 222;
var a = {
name: 111,
say: function () {
console.log(this.name);
},
};
var fun = a.say;
fun();
a.say();
题目一解析:
var fun = a.say = function () {
console.log(this.name);
},
即
function fun () {
console.log(this.name);
}
fun()函数直接使用,即fun.call(window),所以打印结果为 window.name,即222
a.say() 这个即 a.say.call(a) 即 fun.call(a) ,a调用fun,所以this指向a,即a.name,即111
题目一答案:
var name = 222;
var a = {
name: 111,
say: function () {
console.log(this.name);
},
};
var fun = a.say;
fun(); // 222
a.say(); // 111
题目二:在题目一的基础上,这次控制台打印出什么?
var name = 222;
var a = {
name: 111,
say: function () {
console.log(this.name);
},
};
var fun = a.say;
fun(); // 222
a.say(); // 111
// 主要看下半部分的控制台输出结果
var b = {
name: 333,
say: function (fun) {
fun();
},
};
b.say(a.say);
b.say = a.say;
b.say();
题目二解析:
// 首先
令 let fn1 = a.say = function () {
console.log(this.name);
},
b.say(a.say)即b.say(fn1)
令 let fn2 = b.say = function (fun) {
fun();
},
b.say(fn1)即fn2(fn1)
所以就是执行fn2(fn1),即fn1(),即直接调用fn1()函数,相当于fn1.call(window)
打印window.name,即222
下面这种解释为什么错误?
a.say = function () {
console.log(this.name);
},
b.say = function (fun) {
fun();
},
所以b.say(a.say) = function (a.say) {
a.say()
},
即b.say(a.say) 最后执行的是a.say(),即是a调用say()函数,即a.say.call(a),所以输出111
这里错误的原因在于:错把最后执行的a.say()当成a.say.call(a)的语法糖了,其实不然。
注意这里a.say()的上下文是
function (a.say) {
a.say()
},
而不是全局作用域下的,是在函数作用域里面的,区分下面两个情况
情况一:
<script>
a.say()
</script>
情况二:
<script>
function (a.say) {
a.say()
},
</script>
// 其次
b.say = a.say = function () {
console.log(this.name);
},
b.say(),这里就是b.say.call(b)的语法糖,所以输出b.name,即333
题目二答案:
var name = 222;
var a = {
name: 111,
say: function () {
console.log(this.name);
},
};
var fun = a.say;
fun(); // 222
a.say(); // 111
// 主要看下半部分的控制台输出结果
var b = {
name: 333,
say: function (fun) {
fun();
},
};
b.say(a.say); // 222
b.say = a.say;
b.say(); // 333