美文网首页
实例解析javascript中的this

实例解析javascript中的this

作者: _小小苏_ | 来源:发表于2018-04-13 14:50 被阅读0次

this关键字是Javascript中最复杂的机制之一。对this的主要理解,即知道在this的绑定对象。不管是在面试中还是在项目开发中,对this的掌握都是必不可少的。
话不多说,先来看一个例子:

//"use strict";   开启严格模式
var name = "global name";
var obj = {
  name:"obj name",
  getName: function(){
    console.log(this.name);  //(1)
    return function(){
      console.log(this.name);  //(2)
    }
  }
}
//运行一下
obj.getName()();   //  "obj name"  "global name"
var getName2 = obj.getName;
getName();   //  "global name"   "global name"

注:标准模式下为上面的输出,但严格模式下(2)会报错 TypeError: Cannot read property 'name' of undefined。
此实例主要有两个this的要点:

  1. 默认绑定隐式绑定。默认绑定是将this绑定到全局变量,但严格模式例外,this会绑定到undefined。默认绑定的情况:独立函数调用,匿名函数。
  2. 隐式绑定时,函数调用中的this会绑定到“拥”或者“包含”这个函数的对象上下文。隐式丢失时,this又会应用默认绑定。
    所以在上面的例子中,在对象obj中声明了一个函数getName(); 调用obj.getName()时,此时为obj对象拥有它,所以它的this绑定到了obj上,即此时(1)的this.name = obj.name; 并且其调用后返回了一个匿名函数。所以obj.getName()();使得匿名函数执行,此时(2)中的this绑定在window上,即输出 "global name"。

当我们再次定义一个getName2 时,它其实是对obj.getName的引用,实际上它引用的仅仅是getName函数,此时的getName2()其实是一个不带任何修饰的函数调用,因此应用了默认绑定,即隐式丢失。
接着上面的例子,再来执行两个函数。

getName2().call(obj);    //"global name"  "obj name"
(getName2.call(obj))();   //"obj name"  "global name"

我想熟悉call用法的人应该都能给出正确答案。这就是this的第三个要点:显式绑定
即函数可以使用call(...)和apply(...)方法来指定this的绑定对象(call和apply的区别在于第二个参数上,从this绑定角度上是一样的)。
getName2().call(obj); 即相当于将回调函数的this显示绑定到obj上,所以第二个输出为obj.name; getName2.call(obj); 相当于将getName2的this绑定到obj上,因此(getName2.call(obj))(); 和 obj.getName()(); 是等效的。

OK,那么我们继续:

var a;
function foo(a){
  this.a = a;
}
foo(1);
var bar = new foo(2);
console.log(a);    //1
console.log(bar.a);    //2

emm,貌似上面的结果很显而易见。但这就是this绑定的第四个规则:new绑定
那就顺便说说使用new来调用函数,或者发生构造函数调用时,会自动执行的操作。
1)创建(构造)一个全新的对象;
2)这个新对象会被执行[[prototype]]连接。
3)这个新对象会被绑定的到函数调用的this。
4)如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象。
最后是四种绑定的优先级:
new绑定 > 显式 > 隐式 > 默认

随堂测试啦~~~

//例1
function foo(){
  console.log(this.a);
}
var obj2 = {
  a:1,
  foo:foo
};
var obj1 = {
  a:2,
  obj2:obj2
};

obj1.obj2.foo();   //1
//例2
function foo(){
  console.log(this.a);
}
function doFoo(fn){
  fn();
}
var obj = {
  a:2,
  foo:foo
};
var a = "global";
doFoo(obj.foo);   //  "global"
//传递参数其实就是一种隐式赋值,相当于var fn = obj.foo;  fn();
//例3
function foo(){
  console.log(this.a);
}
var obj1 = {
  a:1,
  foo:foo
};
var obj2 = {
  a:2,
  foo:foo
};
obj1.foo();  //1
obj2.foo();  //2

obj1.foo.call(obj2);  //2
obj2.foo.call(obj1);   //1

相关文章

网友评论

      本文标题:实例解析javascript中的this

      本文链接:https://www.haomeiwen.com/subject/myfckftx.html