Javascript中严格模式和正常模式下this的指向

在 Javascript中 this 的指向不是固定不变的,它会随着执行环境的改变而改变。但它始终会指向该方法运行时所在的环境(调用函数的那个对象)。

函数和方法区别: 方法依赖对象调用,函数不依赖对象。

本文以浏览器中的Javascript环境讲解,而非Node环境。

全局作用域中的this

在全局作用域中,无论是否为严格模式,this指向的都是window对象。

非严格模式
console.log(this===window);//true
严格模式
"use strict";
console.log(this===window);//true

全局作用域中函数中的this

非严格模式【默认绑定】

默认绑定:函数调用时无任何调用前缀,该函数将会自动绑定到window对象(全局对象),使之成为window对象的一个方法。也就是说该函数实际有个隐式前缀window。故全局作用域中普通函数this指向的是window对象。

function foo(){
	console.log(this===window);
}
foo();//true
window.foo();//true
严格模式

由于非严格模式下有些写法其实是不大符合逻辑的,比如在顶级作用域中使用var声明的变量会自动成为全局变量,还有调用普通方法时会自动将方法绑定到window对象中。

严格模式中顶级作用域下调用普通函数的时候,不会自动将函数绑定到window对象,导致函数的调用者丢失,此时函数内的this相当于未初始化的普通变量,为undefined

"use strict";			
function foo(){
	console.log(this===window);
}
foo();//false
window.foo();//true

对象的方法中的this【隐式绑定】

无论是否为严格模式,如果函数调用时,前面存在调用它的对象,那么this就会隐式绑定到这个对象上(多个对象在前,采用最近原则)

非严格模式
var obj = {
	innerObj: {
		foo: function() {
			console.log(this);
		}
	}
};

obj.innerObj.foo();//{foo:f} 也就是innerObj对象
var func=obj.innerObj.foo
func();//window
严格模式
"use strict";			
var obj = {
	innerObj: {
		foo: function() {
			console.log(this);
		}
	}
};

obj.innerObj.foo();//{foo:f} 也就是innerObj对象
var func=obj.innerObj.foo
func();//undefined

隐式丢失就是指隐式绑定的函数丢失绑定对象,从而默认绑定到全局或者undefined(取决于是否使用严格模式)

显式绑定this

无论是否为严格模式,通过callapply以及bind方法改变this的行为,this都指向绑定的对象。需要注意的是非严格模式下使用call之类的方法改变this指向时,指向参数提供的是null或者undefined,那么 this 将指向全局对象。

非严格模式
var name = 'Joe';
var obj = {
	name: 'Free',
	fn: function() {
		console.log(this.name);
	}
};
var obj2={name:'Fly'}

obj.fn.call(obj2)//Fly
obj.fn.call(null)//Joe
obj.fn.apply(obj2)//Fly
obj.fn.bind(obj2)()//Fly
严格模式
"use strict";		
var name = 'Joe';
var obj = {
	name: 'Free',
	fn: function() {
		console.log(this.name);
	}
};
var obj2={name:'Fly'}

obj.fn.call(obj2)//Fly
obj.fn.call(null)//Uncaught TypeError: Cannot read property 'name' of null
obj.fn.apply(obj2)//Fly
obj.fn.bind(obj2)()//Fly

构造函数的this【new绑定】

无论是否为严格模式,只要是通过构造函数new对象,构造函数中的this都指向这个新对象。

new的时候会做下面这四件事:

(1)开辟内存空间,在内存中创建一个新的空对象。

(2)让 this 指向这个新的对象。

(3)执行构造函数里面的代码,给这个新对象添加属性和方法。

(4)返回这个新对象(所以构造函数里面不需要 return
// ES5构造函数
let Dog = function (name, age) {
  // 1.创建一个新对象,赋予this,这一步是隐性的,
  //   let this = {};
  // 2.给this指向的对象赋予构造属性
  this.name = name;
  this.age = age;
  // 3.如果没有手动返回对象,则默认返回this指向的这个对象,也是隐性的
  // return this;
};
const myDog = new Dog();

非严格模式
function Person(){
	this.name=name
}
let Joe=new Person('Joe')
console.log(Joe.name);//Joe
严格模式
"use strict";
function Person(){
	this.name=name
}
let Joe=new Person('Joe')
console.log(Joe.name);//Joe

拓展:this绑定优先级

如果在某个调用位置应用了多条规则,如何确定哪条规则生效?
显式绑定 > 隐式绑定 > 默认绑定
new绑定 > 隐式绑定 > 默认绑定

    obj.foo.call(obj2); // this指向obj2 显式绑定比隐式绑定优先级高。
    new obj.foo(); // this指向new新创建的对象 new绑定比隐式绑定优先级高。

箭头函数的this

箭头函数的this指向取决于外层作用域(最近的那个)中的this,外层作用域或函数的this指向谁,箭头函数中的this便指向谁。

箭头函数的 this 一旦绑定了上下文,就不会被任何代码改变。

非严格模式
var foo=()=>{
	console.log(this);
}
var obj={}
foo.call(obj);//window
严格模式
"use strict";
var foo=()=>{
	console.log(this);
}
var obj={}
foo.call(obj);//window

事件处理函数中的this

在事件中,this 表示接收事件的元素。

<input type="text" onclick="this.value=this" placeholder="点击查看事件中this指向"/>

在这里插入图片描述

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值