JavaScript中的this指向

155 阅读2分钟

this使用场景简单归纳:
前置说明: (优先级: new > call、apply、bind > 对象.方法 > 直接调用)

一:全局上下文

描述:默认指向window, 严格模式下指向undefined

  • 例1
var a = 10;
this.a = 20;
a = 30;
console.log(this);  // window
function say(){
   console.log(this.a);   // 30
}
say()

二:对象调用

描述:严格对象.方法的形式调用,this指向前面的对象

  • 例1
var a = 20;
var person = {
    a: 30,
    say: function(){
    	console.log(this.a);
    }
}
person.say();  // 30
var newSay = person.say;
newSay();      // 20

三:借助call、apply函数

描述:强制绑定,this指向call、apply第一个参数

  • 例1
var a = 10;
function say(){
   console.log(this.a);
}
var person = { a: 20 };
say.call(person);

四:构造函数

描述:this指向新生成的实例对象

  • 例1
function Person(name){
    this.name = name;
}
Person.prototype.sayThis = function(){
    console.log(this);
}
var onePerson = new Person("min");
onePerson.sayThis();   // {name: "min"}
  • 实例化过程 (1) 创建一个新的空对象
    (2) 将构造函数的this指向这个新对象;将新对象原型指向构造函数原型(过程中构造属性需要回指)
    (3) 执行构造函数的代码,为这个对象添加属性,方法等
    (4) 返回这个新对象

额外:箭头函数

描述: 箭头函数不会创建自己的执行上下文,而是从定义它的外部函数中获取 this,
           (即this向上查找,指向最近的非箭头函数的this,直到window)

  • 例1
var a = 20;
var person = {
   a: 30,
   say: ()=>{
       console.log(this.a);
   }
}
person.say();  // 20

思考题

  • 题1 (提示: object并不像函数,不形成自己的作用域)
var c = {
    a: 60,
    foo: function(){
    	var a = 1;
        var obj = {
            a: 10,
            c: this.a + 20,
            fn: function(){
            	console.log(this.a);
            }
        }
        obj.fn();
        return obj.c;
    }
}
console.log(c.foo());
  • 题2 (提示: 正常下dom对象也可当作对象,只是老ie中attachEvent比较怪异)
<!DOCTYPE html>
<html>
<head>
	<title>this</title>
</head>
<body>
	<h1 onclick="say()">hello</h1>
	<h2 id="dom">world</h2>
	<h3 id="ele">min</h3>
	<h4 id="ie">min</h4>
	<script type="text/javascript">
		function say(){
		    console.log(this)
		}
		var dom = document.querySelector("#dom");
		var ele = document.querySelector("#ele");
		var ie =document.getElementById("ie");
		dom.onclick = function(){
		    console.log(this)
		};
		ele.addEventListener("click", ()=>{
		    console.log(this);  // 回调不用箭头函数又是什么?
		});
		if("attachEvent" in window){
		    ie.attachEvent("click", function(){
		        console.log(this)
		    })
		}
	</script>
</body>
</html>