【JS】js回调this问题

两个调用 第二次进行回调的时候 this 标记1和 this 标记2值不一样
这是为何?

 function a (val, callback) {

callback.call(a,val,callback)

}

a(1,function b (val ,callback) {

console.log(this, '标记1')

console.log(val)

console.log(callback)

callback(2,function c(val, callback){

console.log(this)

console.log(val)

console.log(callback)

console.log('over')

})

})

console.log('-----分割线-------')

a(1,function b () {

console.log(this, '标记2')

console.log(arguments[0])

console.log(arguments[1])

arguments[1](2,function c(){

console.log(this)

console.log(arguments[0])

console.log(arguments[1])

console.log('over')

})

})

【JS】js回调this问题

回答

第一步,先看函数a定义

【JS】js回调this问题

观察callback,上图中一共有三个callback,分别是

  1. 函数a的参数中的callback
  2. 绑定在a上执行的callback, 它执行时对应的this是函数a
  3. 2号callback执行时的参数中的callback,3号callback执行时并没有明确指定this绑定谁,在执行时确定

第二步,简化你的试验代码,突出this

function a(val, callback) {

callback.call(a,val,callback);

}

a(1, function b(val ,callback) {

console.log(this, '标记10的this');

callback(2, function c(val, callback){

console.log(this, '标记11的this');

});

});

console.log('-----分割线-------');

a(1, function b() {

console.log(this, '标记20的this')

arguments[1](2, function c(){

console.log(this, '标记21的this');

});

});

第三步, 分析分割线上半部分执行结果

a(1, function b(val ,callback) {

console.log(this, '标记10的this');

callback(2, function c(val, callback){

console.log(this, '标记11的this');

});

});

//输出: a 标记10的this

//输出: window 标记10的this

//输出: window 标记11的this

进一步简化,上面代码实际是 a(1, b), 结合第一步的图,

  1. b第一次执行时,对应第一步图中2号callback,

    1. 第一行开始执行:输出是 "a 标记10的this“

    2. 第二行开始执行:callback对应第一步图中3号callback,在此代指函数b,故等价于 b(2,c), b被第二次执行。

  2. b第二次执行时b(2,c),并未绑定任何对象,默认在window上执行,故this是window

    1. 第一行开始执行:输出 "window 标记10的this"

    2. 第二行开始执行:等价于 c(2,c)
    3. 第三行开始执行:c并未绑定任何对象,默认绑定在window上。 输出 ”window 标记11的this“

第四步, 分析分割线下半部分执行结果

a(1, function b() {

console.log(this, '标记20的this')

arguments[1](2, function c(){

console.log(this, '标记21的this');

});

});

//输出: a 标记20的this

//输出: arguments 标记20的this

//输出: arguments 标记21的this

进一步简化,上面代码实际是 a(1, b), 结合第一步的图,

  1. b第一次执行时,对应第一步图中2号callback,

    1. 第一行开始执行:输出是 "a 标记20的this“

    2. 第二行开始执行:arguments[1]对应第一步图中3号callback,在此代指函数b,特别注意等价于绑定在arguments上执行b(2,c), b被第二次执行,为了好理解,你就理解为 arguments.b(2,c);
    3. 插播一段,数组内函数执行后,这个函数中的this默认指向数组:

    var arr = [function(){console.log(this)}];

    arr[0](); // 输出的this的是 arr

  2. b第二次执行时arguments.b(2,c) (注意,只是为了好理解,实际是arguments[1]代b执行。),绑定在arguments对象上执行b,故this是arguments

    1. 第一行开始执行:输出 "arguments 标记20的this"

    2. 第二行开始执行:等价于 arguments.c(2,c) (注意,只是为了好理解,实际是arguments[1]代c执行。)
    3. 第三行开始执行:c也绑定在arguments上。 输出 ”arguments 标记21的this“

翻译一下你的代码,说实话,你这命名不改一下真是谁都看不懂。

 function a(val, aCallback) {

aCallback.call(a, val, aCallback)

}

a(1, function b(val, bCallback) { //b.call(a,1,callback) -> b(1,a.callback) -> bCallback = function b(val,bCallback) -> this指向a

console.log( this, '标记1')

bCallback(2, function c(val, cCallback) { // b() -> bCallback = function c -> bCallback是个function 采用默认绑定 this指向window

console.log('over 1')

})

})

a(1, function b() { //b.call(a,1,callback) -> b(1,a.callback) -> bCallback = function b(val,bCallback) -> this指向a

console.log( this, '标记2')

arguments[1](2, function c() { // b() -> bCallback = function c -> 由于arguments是个对象 采用隐式绑定 this指向arguments

console.log('over 2')

})

})

抱歉看不下去, 只看了前面两位的答案,大概就是这样了。

以上是 【JS】js回调this问题 的全部内容, 来源链接: utcz.com/a/83798.html

回到顶部