10.8.JS-this,arguments

发布于 2022年 05月 04日 07:27

1. this

  1. 函数预编译过程this-->window
  2. 全局作用域里this-->window
  3. call/apply 可以改变函数运行时this指向
  4. obj.func(); func()里的this指向obj
  • this指向判断
var name = 'bcd';
var obj = {
  a: function(){
    console.log(this.name);
  },
  name: 'abc'
}
obj.a(); // 打印 'abc', 此时this-->obj,this.name --> obj.name,如果没有 name 属性,会按原型链向上寻找,直到找到 Object, 没有的话打印 undefined
var c = obj.a;
c(); // 打印 'bcd' 此时函数体this-->c, 函数体赋给变量 c 且未执行, 让 c 执行, 此时 c 在全局环境上, 所以this-->window, window.name 为 'bcd'
  • this练习题
var name = '222';
var a = {
  name: '111',
  say: function () {
    console.log(this.name);
  }
}
var fun = a.say;
fun();
a.say();
var b = {
  name: '333',
  say: function (fun) {
    fun()
  }
}
b.say(a.say);
b.say = a.say;
b.say();
// 预编译阶段
// GO {
//   name: undefined,
//   a: undefined,
//   fun: undefined,
//   b: undefined,
// }
// 代码执行阶段 GO 变化
// GO {
//   name: 222,
//   a: {...},
//   fun: function(){...}
// }
// fun表达式执行, 此时函数体的this-->window, window.name == name == '222'; 打印 '222'
// a.say(); 函数执行,此时函数体的this-->a, a.name == '111'; 打印 '111'
// 代码继续执行 GO 变化
// GO {
//   name: 222,
//   a: {...},
//   fun: function(){...},
//   b: {...}
// }
// b.say(a.say); 先执行 b.say 函数, 然后对执行 a.say 函数, 此时 函数体的 this --> a, a.name == '222'; 打印 '222'
// b.say = a.say; 对b的say属性重新进行赋值为 a.say 函数体
// b.say(); 执行新的 b.say 函数,此时函数体this->b b.name == '333'; 打印 '333' 
// 222 111 222 333

2. arguments

  1. arguments.callee
  2. func.caller

2.1. callee含义

function test(){
  console.log(arguments.callee); // 打印函数本身 function test(){...}
}
test();

2.2. callee用处

  • 在没有函数名时, 函数执行需要调用自身(递归...)
// 阶乘
var num = (function(n){
  if(n == 1){
    return 1;
  }
  // return n * 阶乘(n-1);
  return n * arguments.callee(n-1);
}(5))
console.log(num); // 120 
//  5!
//  5 * 4!
//  5 * 4 * 3!
//  5 * 4 * 3 * 2!
//  5 * 4 * 3 * 2 * 1

2.2. caller含义

function test(){
  demo();
}
function demo(){
  console.log(demo.caller); // test(){ demo(); } 函数执行的上下文
}
test();

推荐文章