《你必须知道的javascript(上)》- 2.this与对象原型

Posted tangge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《你必须知道的javascript(上)》- 2.this与对象原型相关的知识,希望对你有一定的参考价值。

1.1 为什么使用this

随着你的使用模式越来越复杂,显式传递上下文对象会让代码变得越来越混乱,使用this则不会这样。当我们介绍对象和原型时,你就会明白函数可以自动引用合适的上下文对象有多重要。

1.2 关于误解

首先需要消除一些关于this的错误认识。

1.2.1 指向自身

先来看个例子:

        function foo(num) 
            console.log("foo: " + num);

            // 记录foo被调用的次数,这里this指向window 
            this.count++; 
        

        foo.count = 0;

        var i;

        for (i = 0; i < 10; i++) 
            if (i > 5) 
                 foo(i);
            
        
        // foo: 6 
        // foo: 7 
        // foo: 8 
        // foo: 9 

        // foo被调用了多少次? 
        console.log(foo.count); // 0 -- WTF?

执行foo.count = 0时,的确向函数对象foo添加了一个属性count。但是函数内部代码this.count中的this并不是指向那个函数对象(指向全局变量 window),所以虽然属性名相同,根对象却并不相同,困惑随之产生。

如果要从函数对象内部引用它自身,那只使用this是不够的。一般来说你需要通过一个指向函数对象的词法标识符(变量)来引用它。

解决方法一:
一种解决方法是用词法作用域:

function foo(num)  
    console.log( "foo: " + num ); 
 
    // 记录foo被调用的次数 
    data.count++; 
 
 
var data =  
    count: 0 
; 

解决方法二:
另一种解决方法是使用foo标识符替代this来引用函数对象:

function foo(num)  
    console.log( "foo: " + num ); 
 
    // 记录foo被调用的次数 
    foo.count++; 
 
foo.count=0; 

然而,这种方法同样回避了this的问题,并且完全依赖于变量foo的词法作用域。

重点:解决方法三:
另一种方法是强制this指向foo函数对象:

function foo(num)  
    console.log( "foo: " + num ); 
 
    // 记录foo被调用的次数 
    // 注意,在当前的调用方式下(参见下方代码),this确实指向foo 
    this.count++; 
 
 
foo.count = 0; 
 
var i; 
 
for (i=0; i<10; i++)  
    if (i > 5)  
        // 使用call(..)可以确保this指向函数对象foo本身 
        foo.call( foo, i ); 
     
 
// foo: 6 
// foo: 7 
// foo: 8 
// foo: 9 
 
// foo被调用了多少次? 
console.log( foo.count ); // 4

以上是关于《你必须知道的javascript(上)》- 2.this与对象原型的主要内容,如果未能解决你的问题,请参考以下文章

面向对象编程思想(前传)--你必须知道的javascript

面向对象编程思想(前传)--你必须知道的javascript(转载)

你如何清除javascript中的焦点?

你怎么知道使用JavaScript是否打开大写锁定?

产品经理向上跳槽,这2点你必须知道

你可能不知道的JavaScript代码片段和技巧(上)