this对象
this
和arguments
一样都是函数内部的关键词
函数的预编译四步:
- 创建
AO
对象 ==>Activated Object
(活动对象)【激活状态】 - 找到形参和变量,把形参和变量作为
AO
对象的属性名,值是undefined
- 实参把值赋给形参
- 在函数中找到函数声明,把函数名作为
AO
对象的属性名,值是函数体
预编译之后才能执行JS代码
function auto (a){
console.log(a);
function heaven(){
console.log(this);
}
heaven();
}
auto(2);也可以这样写window.auto(2)
auto:AO{
a:undefined -->a:2
this:window(GO)
}
heaven:AO{
this:window(GO)
}
window{
a:2,
auto:function(){};
}
结论: this
默认指定window
(默认):在每次函数预编译的时候系统都会添加上this
的
function auto(a){
console.log(this);//window
}
auto(2);
var obj = {
name:"我是对象",
a:auto//属性名a,属性值是auto这个函数声明
//a属性是储存上面的函数
}
obj.a();//obj.查询当前obj上面的a属性a是当前的函数声明(a:auto),
a()是启动函数
//就是点前obj这个对象调用了上面的函数,通过对象启动了auto这个函数
this
是一个对象,它指向了调用函数的那个对象(到底是被谁启动了我这个函数)
- 只要是函数名字加上()执行
this
-->window
- 通过对象调用了函数
this
–> 调用函数的对象
this练习
var name = "heaven";
function showName(){
console.log(this.name);
}
var person1 = {
name:"oldsix",
sayName:showName
}
var person2 = {
name:"xiaoming",
sayName:function(){
var fun = person1.sayName;
fun();
}
}
person1.sayName();//olsix
person2.sayName();//heaven
call apply
call apply
可以修改函数执行时的this
指向
function auto(){
console.log(this);
}
auto();
当前函数声明打印的是this
默认指向的是window
对象,那么如何打印的时候不指向window
???
call
可以修改函数执行时的this
指向
function auto(){
console.log(this);
}
auto.call([1,2,3]);
通过call
关键词修改了this
指向,把this
修改了[1,2,3]
的数组
在函数预编译的时候this
会把默认的window
替换成call关键字替换的内容
如下:
function auto(){
console.log(this);
/*
AO{
this:window-->{name:"heaven"}
}
*/
}
auto.call({name:"heaven"});
用call
关键词修改的this
的指向,如果修改的是多个**会不会变成实参被形参给接收呢??
单一形参,对应单一实参,碰见call关键词修改this指向时
function auto(a){
console.log(this);
console.log(a);
}
auto.call({name:"heaven"});
实参的数量<形参的数量,没有接受到实参的形参值是undefined
,表示没有接
收到实参
多个形参,对应多个实参,碰见call关键词修改this指向时
function auto(a,b,c,d){
console.log(this);
console.log(a);
console.log(b);
console.log(c);
console.log(d);
}
auto.call({name:"heaven"},null,12,"yellow");
auto.call
(对象,实参1,实参2,实参3… ),括号里面的第一个肯定是用call
修改this
的指向,第二个是实参1,实参2,…
第二个实参以后的都是形参和实参一一对应的
用call
关键词修改this
指向时,修改的值是undefined,那修改的结果是不是undefined
function auto(){
console.log(this);
}
auto.call(undefined);
auto.call([1,2],[2,3,4,4]); // --> [1,2]
auto.call({name:'heaven'}) --> {name:'heaven'}
auto.call(function(){}) --> function(){}
auto.call(null); --> window
auto.call(undefined) --> window
当undefined
和null
,传进来的时候call
无法修改this的指向
,值还是window
apply
也可以修改函数执行时的this
指向
function auto(){
console.log(this);
}
auto.apply([1,2]);
无论是call
还是apply
,都可以在传同样的一个对象过去的时候都能修改this
的指向
那call
和apply
的区别在哪
function auto(){
console.log(this);
}
auto.apply([1,2]);
auto.call([1,2]);
用call修改this的指向和传递参数
function auto(a,b,c){
console.log(this);
console.log(a,b,c);
}
auto.call([1,2],"heaven",10,"lala")
//第一个值后面是实参和上面的形参是一一对应的
用apply修改this的指向和传递参数
function auto(a,b,c){
console.log(this);
console.log(a,b,c);
}
auto.apply([1,2],[1,"heaven",10]);
//第一个值后面的中括号里面的是实参和上面的形参是一一对应的
结论:
call
修改this
指向的后面可以传多个实参apply
修改this
指向的后面,在传递参数的时候必须把使用实参放在一个数组中才能传递进去
练习:
function add(c,d){
/*
AO{
this:obj,
c:undefined-->c:3
d:undefined-->d:4
}
AO{
this:obj,
c:undefined-->c:5
d:undefined-->d:6
}
*/
return this.a + this.b + c + d;
}
var obj = {
a:1,
b:2,
}
console.log(add.call(obj,3,4));//1+2+3+4=10
console.log(add.apply(obj,[5,6]));//1+2+5+6=14