js中的this对象

2017-12-18  本文已影响0人  大写的Q

js中的this总会指向一个对象,具体是哪个对象就由运行时函数的执行环境而决定了。
在实际应用中,this的常用指向大致为4种:

1. 作为对象的方法调用

函数作为对象的方法被调用时,this指向该对象

var obj = {
  a: 1,
  getA: function() {
    alert(this===obj);
    alert(this.a);
  }
}

obj.getA(); // 输出:1
2. 作为普通函数调用

函数作为普通函数方式被调用时,this指向全局对象,即window对象。

window.name = 'global';
var myObj = {
  name: 'func',
  getName: function() {
    return this.name;
  }
}

var getName = myObj.getName;
console.log(getName()); // 输出:global
3. 构造器调用

new运算符使得构造器看起来更像一个类。当用new运算符调用函数时, 该函数总会返回一个对象,通常情况下this就指向返回的这个对象。例如:

window.name = 'aaa';
var myObj = function(){
  this.name = 'bbb';
}

var obj = new myObj();
alert(obj.name); // 输出:bbb

但是如果构造器显式地返回了一个object类型的对象,那么运算结果最终会返回这个对象。

window.name = 'aaa';
var myObj = function(){
  this.name = 'bbb';
  return {
    name: 'ccc'
  }
}

var obj = new myObj();
alert(obj.name); // 输出:ccc

或者:

window.name = 'aaa';
var myObj = function(){
  this.name = 'bbb';
  var anotherName = {
    name: 'ccc'
  }
  return anotherName;
}

var obj = new myObj();
alert(obj.name); // 输出:ccc
4. Function.prototype.call或者Function.prototype.apply调用

用call或者apply可以动态改变传入函数的this

var obj1 = {
  name: 'aaa',
  getName: function() {
    return this.name;
  }
}

var obj2 = {
  name: 'bbb'
}

console.log(obj1.getName()); // 输出:aaa
console.log(obj2.getName.call(obj2)); // 输出:bbb

或者:

 var obj1 = {
 name: 'aaa'
 }

 var obj2 = {
 name: 'bbb'
 }

 window.name = 'global'

 var getName = function() {
 alert(this.name);
 }

 getName(); // 输出:global
 getName.call(obj1); //输出: aaa
 getName.call(obj2); //输出:bbb

之前面试遇到过一个问题,下面这种情况会不会报错,为什么?

var getId = document.getElementById;
getId('div1');

答案是会报错,因为正常情况下getElementById方法作为document对象的属性被调用时,this是指向document的,但此时getId引用了getElementById,又被调用的情况就属于普通函数调用了,函数内部的this指向了windows而不是document。可以用apply对这个错误进行修正:

document.getElementById = (function(func){
  return function() {
    return func.apply(document, arguments);
  }
})(document.getElementById);

var getId = document.getElementById;
var div = getId('div1');
console.log(div.id); // 输出:div1

参考:
《Javascript设计模式与开发实践》

上一篇下一篇

猜你喜欢

热点阅读