js-浅析this指向

    在理解this的绑定过程之前,首先要理解调用位置:调用位置就是函数在代码中被调用的位置(而不是声明的位置)。对于正常的函数调用,this的绑定分为以下几种:
1. 默认绑定

    如果函数是在全局上直接使用不带任何修饰的函数引用进行调用,此时只能使用默认绑定。即在非严格模式下,this指向window。而如果是在严格模式下,则不能对全局对象进行默认绑定,此时的this会指向undefined。如下:

  function fn(){
       console.log(this.a);
   }
   var a = 2;
   fn();

    此时console.log的结果为2
2. 隐式绑定

    隐式绑定是需要考虑函数是否是作为对象的一个属性值进行调用。此时this会指向包含该函数的对象。严格来说,对象属性引用链上只有上一层或者最后一层在调用位置上起作用。如下,console的打印结果为1:

var a = 42;
function fn(){
    console.log(this.a);
};
var obj1 = {
    a:1,
    fn:fn
};
obj1.fn();

    值得注意的是,隐式绑定会发生丢失绑定对象的现象。即调用对象不再像前文一样直接运行对象中属性值中的函数。而是先将该属性值赋值给一个变量,后运行这个赋值后的变量。此时this将不再指向包含该属性值的对象。而是决定于赋值后的变量在哪调用。如下:

var a  = 42;
function fn(){
    console.log(this.a)
};
var obj1 = {
    a:1,
    fn:fn
};
var b = obj1.fn;
b();

    此时console的结果为42.原因就在于b虽然是obj1.fn的引用,但是实际上它引用的是fn函数本身。因此b()此时是一个不带任何修饰符的函数,this的指向将按照默认绑定规则进行绑定。

    除了这种情况,回调函数进行参数传递时,也会发生上述情况。

  1. 显式绑定

        通过一些方法,可以将this强制绑定到固定元素上。这种操作便是显式绑定。常用的办法为apply()和call()。这两个方法的第一个参数是一个对象,是给this准备的,接着在调用函数的时候,将this绑定在该对象上。这两个方法的区别在于call()的参数为一个一个的参数。而apply(),其参数为数组形式,调用函数中接收时为arguments。

        显式绑定中有一种写法是可以解决绑定丢失的情况。即在函数调用的时候使用call或者apply,强制将函数的this绑定到call或apply的第一个参数上。即

function fn(){
    console.log(this.a);

}
var obj = {a:2};
var bar = function(){
    foo.call(obj);
}
bar();

    此时foo的this被强制绑定在obj上,打印结果就为2。

     在ES5中提供了一种方法,Function.prototype.bind。其z作用原理也跟上述写法类似。

function fn(something){
    return this.a + something;
}
var obj = {
    a :2
}
var bar = fn.bind(obj);
var b = bar(3);
  1. new绑定

        在面向对象编程(oop)中,都会使用new来调用一些函数。而这些函数被称为构造函数。构造函数是用来初始化新创建的对象。当我们使用new来调用一个函数时,该函数内部的this会指向一个对象。在没有重新定义返回值的前提下,该函数返回的对象和内部指向的对象是同一个对象。

function fn(userName,age){
   //var object = new Object();
   // this = new Object;
    this.name = userName;
    this.age = age;
}
var girl = new fn('lily','23');

    上述代码中注释中的代码只是为了演示,不具有可操作性。实际上在调用构造函数中,this所指向的对象是由js内部创建,而非外部编程可操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值