本文共 3950 字,大约阅读时间需要 13 分钟。
一、this的指向
this的指向是指谁调用它,那么this就指向谁
全局环境中的this
1)浏览器环境:无论是否在严格模式下,在全局执行环境中(在任何函数体外部)this 都指向全局对象 window 2)node 环境:无论是否在严格模式下,在全局执行环境中(在任何函数体外部),this 都是空对象 {}是否是 new 绑定
1)如果是 new 绑定,并且构造函数中没有返回 function 或者是 object,那么 this 指向这个新对象 2)构造函数返回值不是 function 或 object,这种情况下 this 指向的是新到的对象 实例代码:function Person(age){ this.age = age; } // 23 // this指向的是这个新的对象 let person1 = new Person("23"); console.log(person1.age);
3)构造函数返回值是 function 或 object,这种情况下 this 指向的是返回的对象
实例代码:function Person2(age){ this.age = age; let obj = { a:"21"}; return obj; } // undefined let person2 = new Person2("hello"); console.log(person2.age);
4)new的实现原理
创建一个新对象 这个新对象会被执行 [[原型]] 连接 属性和方法被加入到 this 引用的对象中。并执行了构造函数中的方法 如果函数没有返回其他对象,那么 this 指向这个新对象,否则 this 指向构造函数中返回的对象 5)new的实例代码:function New(func){ let target = { }; target._proto_ = func.prototype; let res = func.call(target); // 排除null的情况 if(res && typeof(res) == "object" || typeof(res) == "function"){ return res; } return target; }
function info(){ console.log(this.age); } var person3 = { age:26, info }; var age = 21; var info = person3.info; // 26 info.call(person3); // 26 info.apply(person3); // 26 info.bind(person3)();
2)如果 call,apply 或者 bind 传入的第一个参数值是 undefined 或者 null,严格模式下 this 的值为传入的值 null /undefined。非严格模式下,实际应用的默认绑定规则,this 指向全局对象(node环境为global,浏览器环境为window)
实例代码:function info2(){ // node环境中,非严格模式为global,严格模式为null // 浏览器环境中,非严格模式为window,严格模式为null console.log(this); console.log(this.age); } var person4 = { age:20, info2 }; // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …} // 24 var age = 24; var info2 = person4.info2; // 严格模式下会报错 // 非严格模式下,node输出undefined,全局变量age不会挂在global // 非严格模式下,浏览器环境中输出24,全局变量age会挂在window info2.call(null);
5.隐式绑定,函数的调用是在某个对象上触发的,即调用位置上存在上下文对象。典型的隐式调用为: xxx.fn()
1)隐式绑定的实例代码:function info3(){ console.log(this.age); } var person5 = { age:26, info3 } // 26 // 执行的是隐式绑定 var age = 18; person5.info3();
// 非严格模式: node环境,执行全局对象 global,浏览器环境,执行全局对象 window // 严格模式:执行 undefined function info4(){ console.log(this.age); } // 28 // 严格模式下会报错,this是undefined // 非严格模式下,node环境会输出undefined,浏览器环境输出28 var age = 28; info4();
let obj = { age:27, info:function(){ return() => { // this继承的是外层上下文绑定的this console.log(this.age); } } }; let person6 = { age:26}; // 27 let info5 = obj.info(); info5(); // 26 let info6 = obj.info.call(person6); info6();
二、this指向的面试题总结
如何正确的判断this? 箭头函数的this是什么?
1)this的绑定规则有四种:默认绑定,隐式绑定,显式绑定,new绑定 2)函数是否在 new 中调用(new绑定),如果是,那么 this 绑定的是新创建的对象,前提是构造函数中没有返回对象或者是function,否则this指向返回的对象/function 3)函数是否通过 call,apply 调用,或者使用了 bind (即硬绑定),如果是,那么this绑定的就是指定的对象 4)函数是否在某个上下文对象中调用(隐式绑定),如果是的话,this 绑定的是那个上下文对象,一般是 obj.foo() 5)如果以上都不是,那么使用默认绑定,如果在严格模式下,则绑定到 undefined,否则绑定到全局对象 6)如果把 null 或者 undefined 作为 this 的绑定对象传入 call、apply 或者 bind, 这些值在调用时会被忽略,实际应用的是默认绑定规则 7)箭头函数没有自己的 this, 它的this继承于上一层代码块的this判断下面this的值
var number = 6; var obj2 = { number:8, fn1:(function(){ var number; // 12 this.number *= 2; number = 3; return function(){ var num = this.number; this.number *= 2; console.log(num); number *= 3; console.log(number); } })() }; // 12 9 8 27 24 var fn1 = obj2.fn1; fn1.call(null); obj2.fn1(); console.log(window.number);
转载地址:http://capg.baihongyu.com/