var name='小张',
age=17;
var obj={
name:'小刘',
objAge:this.age,
myFun:function(){
console.log(this.name+'年龄'+this.age);
console.log('查看对象内'+this.objAge)
}
}
obj.myFun()
//小刘年龄undefined
//查看对象内17
var db={
name:'德玛',
age:99
}
var db2={
name:'伽罗',
}
obj.myFun();
obj.myFun.call();//小张年龄17 此时this指向window
obj.myFun.call(db);//德玛年龄99
obj.myFun.call(db2);//伽罗年龄undefined 说明传入对象替换了this,
obj.myFun.apply(db);//德玛年龄99
obj.myFun.bind(db)();//德玛年龄99---->bind 返回的是函数,必需调用执行
var obj2={
name:'小刘',
objAge:this.age,
myFun:function(fm,t){
console.log(this.name+'年龄'+this.age,'来自'+fm+'去往'+t);
}
}
//call、 bind、 apply 这三个函数的第一个参数都是this的指向对象
//|->call可以传入多个参数,多个参数逗号隔开
obj2.myFun.call(db,'江西','深圳');//德玛年龄99 来自江西去往深圳
//|->apply只能传入两个参数,所以其第二个参数往往是作为数组形式传入
obj2.myFun.apply(db,['江西','深圳']);//德玛年龄99 来自江西去往深圳
//|->bind除了返回函数以外,它的参数和call 一样
obj2.myFun.bind(db,'江西','深圳')();//德玛年龄99 来自江西去往深圳
//|->此处测试是吧'江西,深圳'作为一个数组传进去,所以参数fm就是'江西,深圳',中间的逗号应该是数组转义的时候产生的
obj2.myFun.bind(db,['江西','深圳'])();//德玛年龄99 来自江西,深圳去往undefined
function fun1() {
this.ccfun1='命名函数_1';
return this
}
function fun2() {
this.ccfun2='命名函数_2'
}
let unnameFun1=function(){
this.ccunnameFun1='匿名函数_return this 1'
return this
}
let unnameFun2=function(){
this.ccunnameFun2='匿名函数_2 un return'
}
let arrowFun1=()=>{
this.ccarrow1 ='箭头函数_1';
debugger
return this
}
let arrowFun2=function(){
this.ccarrow2 ='箭头函数__2'
}
//测试命名函数
console.log('----------return this;new----------')
// 带this返回
var fun1_new=new fun1();
console.log(fun1_new.ccfun1)//命名函数_1 返回的this中绑定了指定变量
console.log(window.ccfun1)//undefined 此变了未绑定在window上 说明函数创建的时候 this是函数内部的this,或者调用者非window
console.log('----------return this;un new----------')
var fun1_unnew=fun1();
console.log(fun1_unnew===window) //true 此处证明 直接调用函数,不使用new创建,函数内部的this指向window
console.log(window.ccfun1) //命名函数_1
console.log('----------unreturn this;new----------')
var fun2_new=new fun2();
console.log(fun2_new.ccfun2)//命名函数_2 此处证明 return this不重要可以省略
console.log(window.ccfun2)//undefined
var fun2_unnew=fun2();
console.log(fun2_unnew===window) //此处证明 在不使用new 和return的情况 返回值既不是函数调用者也不是window
console.log(fun2_unnew) //undefined 此处证明 直接调用函数,不适用new创建,函数内部的
console.log(window.ccfun2) //命名函数_2
/* 总结 命名函数
1:new 一定会有返回 返回值是其调用者
var fun1_new=new fun1() <==> var fun1_new=new fun1(this:fun1_new);
2:直接调用函数,函数内部的this会指向window 此时return 决定是否有返回
var fun1_new=fun1() <==> var fun1_new=fun1(this:window);
*/
//测试匿名函数
console.log('------匿名函数----return this;new----------')
// 带this返回
var unnameFun1_new=new unnameFun1();
console.log(unnameFun1_new.ccunnameFun1)//匿名函数_return this 1 同上命名函数测试
console.log(window.ccunnameFun1)//undefined 同上命名函数
console.log('----------return this;un new----------')
var unnameFun1_unnew=unnameFun1();
console.log(unnameFun1_unnew===window) //true 此处证明 直接调用函数,不使用new创建,函数内部的this指向window
console.log(unnameFun1_unnew.ccunnameFun1) //命名匿名函数_return this 1函数_1
console.log('----------unreturn this;new----------')
var unnameFun2_new=new unnameFun2();
console.log(unnameFun2_new.ccunnameFun2)//命名函数_2 此处证明 return this不重要可以省略
console.log(window.ccunnameFun2)//undefined
var unnameFun2_unnew=unnameFun2();
console.log(unnameFun2_unnew===window) //此处证明 在不使用new 和return的情况 返回值既不是函数调用者也不是window
console.log(unnameFun2_unnew) //undefined 此处证明 直接调用函数,不适用new创建,函数内部的
console.log(window.ccunnameFun2) //命名函数_2
/* 总结 匿名函数
1:new 一定会有返回 返回值是其调用者
var fun1_new=new fun1() <==> var fun1_new=new fun1(this:fun1_new);
2:直接调用函数,函数内部的this会指向window 此时return 决定是否有返回
var fun1_new=fun1() <==> var fun1_new=fun1(this:window);
*/
console.log('------箭头函数----return this;new----------')
//let arrowFun1_new = new arrowFun1();
//console.log(arrowFun1_new.ccarrow1)//error 箭头函数不能new 使用
let arrowFun1_unnew=arrowFun1();
console.log(arrowFun1_unnew.ccarrow1)//error 箭头函数不能new 使用
console.log(window==arrowFun1_unnew)//true 箭头函数内部使用this==window
let arrowFun2_unnew=arrowFun2();
console.log(window==arrowFun2_unnew)//false 箭头函数是否有返回值由return决定
总结 一 命名函数 和 匿名函数 中的this
1 函数中的this由调用者决定 new创建的函数 函数的调用者是创建函数的变量,非new方法调用函数 函数的调用者将是window
2 new 和 return同时决定是否产生返回值,new决定由返回值的优先级高于return ,在不存在new的情况下 由return决定
3 如果想通过创建者调用函数内部参数及方法 应该在函数内部使用'this.xxx'进行绑定
二 箭头函数
1 箭头函数不能使用new 创建函数实例
2 箭头函数是否有返回值由return决定
3 箭头函数内的this指向window
三 call,apply,bind中的this
这三个函数作用就是更改调用者中this的指向,很多教程介绍是传入对象调用调用者
中函数,有点拗口和不好理解,这种说法把传入对象当成主体和执行者,有点类似于你请鲍鱼,你是原对象,
请吃鲍鱼是执行方法,鲍鱼是方法中this绑定的喜欢的吃食物,现在通过call,apply,bind绑定对象,
这个对象用同事表示,同事喜欢吃的是龙虾,绑定之后的结果就变成你请吃龙虾,同事喜欢吃的食物替换
请吃方法中的this绑定的食物,这个过程顺序说法是你请吃的朋友喜欢的龙虾,逆序说法是朋友让你请
吃的东西是朋友喜欢的龙虾。理解起来有点绕,而我个人理解的就是我请吃东西 ,具体
是什么东西,由我调用的对象决定,类似于obj2.myFun.call(db,'江西','深圳')中,db是被
调用的对象,db对象替换了调用方法中的this,如果偏要解释成db对象调用了调用者的方
法,两个的效果是一样的,执行的方法是同一个,this都是传入对象,如果方法中this的
属性在传入对象中不存在,则这个属性为undefind。
1 传入对象替换执行方法中的this
2 方法中的this是替换,不是深度复制
3 在没有传入对象的时候 ,执行方法中的this指向window
四 扩展 如果单纯想通过返回值调用调用原函数方法 可以通过原型绑定
function Person(first, last, eye) {
this.firstName = first;
this.lastName = last;
this.eyeColor = eye;
}
Person.prototype.age=function(age){
this._age=age;
};
var p1 = new Person("John", "Doe", "blue");
p1.age(20);
var p2 = new Person("li", "li", "black");
p2.age(15);
console.log(p1._age) //20
console.log(p2._age) //12
age();方法内的this执行被创建的对象
网友评论