本文的主要目的是弄清楚为啥子this指向是这玩意,如果有哪位大神知道,请在评论区评论谢谢!
首先:this指向的是一个object对象
非严格模式
全局
console.log(this) // window
分析上面的代码:在全局执行上下文的创建阶段this通过全局的作用域中[[scope]]属性查找到 window对象,确定了this指向。
不清楚[[scope]]和执行上下文请阅读
普通函数
function fun1(){
function fun2() {
console.log(this) // window
}
fun2()
}
fun1()
分析上面的代码: 当fun2被调用时,fun2的执行上下文被创建,首先判断调用者(fun2)的类型是不是Object,是就把this指向其本身,否则,this通过[[scope]]属性找到 fun1 但是,因为fun1的type不是object而是function,所用this继续往上找 找到window
用代码描述一下(以上代码不可执行只是模拟):
fun2.[[scope]] = [f2,f1,window]
if(fun2.type === Object){
fun2.this = fun2
return false
}
for(let i = 0 ; i<fun2.[[scope]].length; i++){
if(fun2.[[scope]][i].type === Object){
fun2.this = fun2.[[scope]][i]
}
}
对象的函数
var obj = {
fun: function(){
console.log(this)
}
}
obj.fun() // obj
分析上面的代码: 当obj.fun被调用时,obj.fun的执行上下文被创建,首先判断调用者(obj.fun)的类型是不是Object,是就把this指向其本身。
new一个对象的函数的内部运行
1.首先会创建一个空的对象obj。
2.然后将this指向新创建的对象obj。
3.将obj对象的__proto__指向构造函数Person的prototype,建立对象和原型的对应关系,在火狐浏览器下,可以通过对象的__proto__属性访问到原型对象,但是在IE浏览器下,此属性没有公开。
4.最后执行构造函数中的代码。
var newFunc = function ( func ){
//1.新建一个空对象,并将 构造函数的原型对象赋给这个空对象
var obj = Object.create(func.prototype);
//2.执行构造函数,相应参数被传入,并将this的上下文指向新创建的对象obj
var ret = func.call(obj);
//3.如果构造函数返回了对象,就舍弃之前创建的对象obj,newObj = ret
if(typeof ret === 'object') return ret;
//4.反之,newObj = obj
else return obj;
}
var foo = function(name){
this.name = name || "100";
}
var newObj = newFunc(foo);
箭头函数 (没有arguments和this指向)
箭头函数的this是借用的外围执行环境的this,外围环境的this指向谁,箭头函数的this就指向谁
(() => {console.log(this)})() // window
var a = {
fun: function(){
(() => {console.log(this)})()
}
}
a.fun() // 对象a
VS严格模式 ‘use strict’;
全局 没有变化
'use strict';
console.log(this) // window
普通函数
'use strict';
function f () {
console.log(this)
}
f() // undefined
对象的函数 没有变化
'use strict';
var obj = {
fun: function(){
console.log(this)
}
}
obj.fun() // obj本身