前言
==此处完全可以略过==
本来写完原型与原型链之后想写原型的继承,再到new操作符,再到this指向的,想以此形成一种知识点连载的错觉,这样的话也方便大家和自己记忆和联想,形成一条完整线索,但是继承感觉比较难写,为了避免我自己的理解给大家造成误导,也一直在不断查询资料和修改调整,目前写到一半,还在加油写,先把后面的放出来了,继承之后补上,偶尔需要插叙嘛哈哈O(∩_∩)O~
==正片开始==
this指向
(一)什么是this
==理解与记忆核心==
this表示对象
取决于函数调用
解释
1.(this表示对象=>当前对象=>当前环境对象=>函数运行时环境对象)
this就是函数运行时所在的环境对象
2.(取决于函数调用=>不同场合,this有不同的值)
函数的不同使用场合,this有不同的值。
小扩展
this永远==指向对象== (JS中一切皆对象,window也是对象)
this指向取决于==函数调用==的位置 (this指向是不定的,无法在事先声明时就得知它的具体指向,因此只有在调用时才能得知它的指向)
this只能在函数体内部使用 (this是函数运行时,内部自动生成的一个对象(执行环境上下文,也称环境对象),this即函数内部环境对象本象,因此只能在函数内部使用)
箭头函数无视上述规则,且优先级最高 (箭头函数中this指向在声明处决定,指向作用域链的父级)
(二)场景举例
先看一张图(图片来源于网上juejin.cn/post/696945…
==理解与记忆核心==
场景优先级
箭头函数 > new > 显示绑定(call/apply/bind)> 隐式绑定(上下文对象obj) > 默认绑定(严格模式undefined,非严格为window)
注:
定时器setTimeout,setInterval中分两种情况,具体看下面例子
闭包或自执行函数被调用可以看做是接收了一个函数字符串,同样要看该字符串函数被调用的环境对象,具体看下面例子。
(1)箭头函数中调用 可以在箭头函数上方重新赋值this给另一个变量来看
function fn() {
setTimeout(() => {
console.log(this.a);
}, 1000);
}
var obj = {
a: 20,
fn,
};
fn.call(obj); // 20,这里可以理解为调用了obj.fn();
转换为es5写法(上下写法等效)
function fn() {
let _self = this
setTimeout(function(){
console.log(_self.a);
}, 1000);
}
var obj = {
a: 20,
fn,
};
fn.call(obj); // 20,这里可以理解为调用了obj.fn();
因此,箭头函数的this指向上一级环境对象
(2)new实例调用 new Person() 指向实例化出来的对象
function Person(name, age) {
this.name = name;
this.age = age;
}
const a = new Person('itachi', 18);
console.log( a.name ); // 这里new Person()构造函数内部的this指向了实例对象,
//即this=>a 所以this.name === a.name === 'itachi'
(3) 显示绑定(call/apply/bind) 绑定到指定的对象
可以参见箭头函数实例
var obj = {
age: 20,
fn:function (name) {
console.log(this.name + '今年' + this.age + '岁')
}
};
const a = { }
obj.fn.call( a , 'itachi'); // 执行了a.fn('itachi');'itachi'今年20岁
//这里可以理解为将obj中的this绑定到 a
//让a拥有了obj中的方法fn(),并调用了 a.fn ('itachi');
(4)隐式绑定(上下文对象obj)
function fn() {
console.log(this.name);
}
var obj = {
name: 'itachi'
};
// 调用 fn(..) 时把 this 绑定到 obj
obj.fn(); //itachi
(5)默认绑定(严格模式undefined,非严格为window) 非严格为window
function fn() {
console.log(this.a);
}
a = 10;
fn(); // 相当于window.fn() 输出10
function fn() {
'use strict';
console.log(this.a);
}
a = 10;
fn(); //相当于undefined.fn()
//输出 TypeError: Cannot read property 'a' of undefined
(6)定时器情况 定时器setInterval或setTimeout是window对象内置的一个方法
var obj = {
fun:function(){
return this ;
}
}
//此时还没执行fn,后面没跟(),即只是作为一堆字符串将其传了过去,执行的时候已经是1000ms以后了,这时是window.setInterval在执行
setInterval(obj.fn,1000); // this指向window对象
//传入时就执行了,因此this指向的是obj对象
setInterval('obj.fn()',1000); // this指向obj对象
(7)函数作为闭包或自执行函数被调用 意味着这个函数不符合以上任意一种调用方式
因为闭包并不属于这个对象的属性或方法。所以在闭包中的this是指向window的
var name = “window”;
var obj={
name: “Object”;
getName: function(){
return function(){
return this.name;
}
}
};
var myobj = obj.getName(); //myobj接收到匿名函数(可以看做以字符串形式接收)
//myObj === 'function(){return this.name;}'
console.log(myobj()); // Window 相当于 return window.name
console.log(obj.myobj()); // Object 相当于 return obj.name
(三)总结与表达
记忆总结(面试时只用记住这关键的几点就行)
什么是this
1.this表示对象 2.取决于函数调用
几种场景优先级:
箭头函数>new实例>显示绑定(call\apply\bind)>隐式绑定(obj上下文对象)>默认绑定(window或undefined)
说一下this?
this表示函数调用时的环境对象(执行上下文) 根据函数调用的不同场景,this指向也不同
- 在箭头函数中:this指向作用域链的父级环境
- 通过new实例化时:this指向新实例化出来的对象
- 通过call/apply/bind调用时:this将绑定到指定的对象 通过上下文(对象)调用时:this指向上下文(该对象)
- 通过一般函数内部调用时:严格模式this指向undefined,否则指向全局对象
——————————————后续待补充