javascript this指针指向?

前言

理解javascript的指针就需要先了解js的执行环境和作用域!执行环境的定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有的变量和函数都保存在这个对象中。虽然我们编写的代码无法访问这个对象,但解析器在处理数据时会在后台使用它。

1、全局执行环境

全局执行环境是最外围的一个执行环境,根据js实现的宿主环境的不同,表示执行环境的对象也不一样。在web浏览器中认为window就是全局执行的对象。因此所有的全局变量和函数都是作为window对象进行创建的。某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有的变量和函数定义也会被销毁。每个函数都有自己的执行环境,当执行流进入一个函数的时候,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出。

2、作用域链

当代码在一个环境中执行时候,会创建变量的一个作用域链(scope chain)。作用域链的用途,是保证对执行环境有权访问的所有的变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在的环境的变量对象,如果这个环境是函数,则将其活动对象作为变量对象。活动对象在最开始的时候只包含一个变量,arguments对象。作用域链的下一个对象来自包含(外部)环境,而再下一个对象则来自下一个包含对象,这样一直延续到全局。

JavaScript由于其在运行期进行绑定的特性,JavaScript 中的 this 可以是全局对象、当前对象或者任意对象,这完全取决于函数的调用方式。JavaScript 中函数的调用有以下几种方式:作为对象方法调用,作为函数调用,作为构造函数调用,和使用 apply 或 call 调用。

看下面第一个例子

var point = { 
      x : 0, 
      y : 0, 
     moveTo : function(x, y) { 
                     console.log(this);//1
                     this.x = this.x + x; 
                     this.y = this.y + y; 
             } 
   };
point.moveTo(1,1); //this 绑定到当前对象,即point对象
console.log(point);//2

第一个位置上的this我们打印的时候发现这里的this指向就是point 这个对象!

point.moveTo()这个方法执行后就更改了对象point的属性x和y

第二个例子

function func(x) { 
       this.x = x;
      console.log(this);

func(2);

我们发现这个时候的this指向是window  why?

这个很好理解,func(2) 可以写成window.func(2);由于任何函数或者全局的属性都是window对象下面的,那么这里的this当然就是window

第三个例子

var point = { 
      x : 0, 
      y : 0, 
      moveTo : function(x, y) { 
                      // 内部函数
                     var moveX = function(x) { 
                                          console.log(this);
                                          this.x = x;
                                          }; 
                     // 内部函数
                     var moveY = function(y) { 
                                          this.y = y;
                                           console.log(this);
                                          }; 
                    moveX(x); 
                    console.log(moveX() in point);//false
                    console.log(moveX() in window);//true
                    moveY(y); 
          } 
}; 
point.moveTo(1,1); 
point.x; //=>0 
point.y; //=>0

上面的代码我们分析下很好理解!执行point.moveTo(1,1)里面有两个方法,moveX和moveY,这两个方法并没有绑定到对象point上,我们知道所有的方法都是属于window对象的,那么这里的moveX和moveY实际上是window上调用的,并不是属于point对象!

第四个例子

function Point(x,y){ 
          console.log(this);//第一次是通过new创建的,返回的是Point{} 它是一个对象,不是单纯的方法了
          this.x = x; // this ?
         this.y = y; // this ?
}
var np=new Point(1,1);//所以这里可以理解成这样
/*
           var np = {
                      x = 1,
                      y =1
               };
*/
np.x;//1
var p=Point(2,2);//这个时候不是通过new创建,就相当于window.Point(2,2),它就绑定到window上了!所以this指向window
console.log(p);//由于函数Point没有返回值,所以这里的p = undefined
p.x;//error, p是一个空对象undefined

总结:


调用形式

this指向
普通函数 全局对象window
对象的方法 该对象
构造函数 新构造的对象

文章参考地址:

http://www.cnblogs.com/isaboy/

http://www.cnblogs.com/isaboy/archive/2015/10/29/javascript_this.html

时间: 2024-10-08 20:59:38

javascript this指针指向?的相关文章

Javascript this指针

Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象. 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript 可以通过一定的设计模式来实现面向对象的编程,其中this “指针”就是实现面向对象的一个很重要的特性.但是this也是Javascript中一个非常容易理解错,进而用错的特性.特别是对于接触静态语言比较 久了的同志来说更是如此. 示例

JavaScript中this指向

一.重点来了,this指向问题: 1.this指向之普通函数. 2.this指向之对象 3.this指向之构造函数 4.this指向之(call,apply)动态更改this指向. 二.具体分析如下 1.普通函数 // 第23行的调用者为null,this指向也为null,// 所以这时js把this指向了window对象,所以弹出的结果是// n,这样不好的是会污染全局函数内带this的操作,不能直接调用; 2.对象 // 第34行是对象的say方法指针指向了一个存在的函数say();// 所

以带头节点的循环链表表示队列,并且只设置一个指针指向队尾元素,实现这样的功能的想法。

用循环链来表示队列,并且只有一个指针.我的想法就是在每个节点添加一个布尔型数据,可以用布尔型数据的true和false来判断此节点是否有数据. 这样生成队列的时候和书上类似. 插入数据的时候,先保存原指针指向的点,然后将此指针向下寻找,直到找到一个节点的布尔是false,而下一个是true时,表示此节点是在队尾,将数据插入,并将次节点的布尔值修改为true.如果找不到这样的节点,说明“上溢”或者是个空的链表.抛出异常. 删除数据的时候,和插入类似,先备份原指针,然后用原指针去不断向下寻找,直到找

打印指针指向的地址值

废话不多说,直接上错误代码: static void print_cpu_src(uint8_t * src,int stride){ int i,j; printf("Magnum cpu src addr == %p, stride ==%d:\n",&src,stride); for (i = 0; i < 11; ++i) { printf("\n"); for (j =0; j < 4; ++j) { printf("%d ,

用父类指针指向子类对象

class A {public:A() { printf("A \n"); }~A() { printf(" ~A \n"); } // 这里不管写不写virtual,删除B对象的时候,都会被执行.因为这个例子是B*指针指向B对象,不是A*指针指向B对象.}; class B : public A{public:B() { printf("B \n"); }~B() { printf("~B \n"); }}; int mai

用结构体指针指向(-&gt;)或结构体变量加点(.)后不出现结构体成员

今天写代码时遇到这么个问题:用结构体指针指向(->)或结构体变量加点(.)后不出现结构体成员,虽然不影响编写,但效率降低,容易出错. 代码入下: stack.h #ifndef __STACK_H__ #define __STACK_H__ #include<stdlib.h> #include<iostream> using namespace std; #define STACK_DEFAULT_SIZE 10; typedef int ElemType; typedef

指针指向整数,字符,及字符串时,相应地址取法

指针指向整数时: 1 #include <iostream> 2 3 int main(void) 4 { 5 using namespace std; 6 int a = 10; 7 int *p = &a; 8 9 cout << "sizeof(p) = " << sizeof(p) << endl; 10 cout << "sizeof(&p) = " << sizeof

指针的指针&amp;指向指针数组的指针

一.指针的指针    指针的指针看上去有些令人费解.它们的声明有两个星号.例如:        char ** cp;    如果有三个星号,那就是指针的指针的指针,四个星号就是指针的指针的指针的指针,依次类推.当你熟悉了简单的例子以后,就可以应付复杂的情况了.当然,实际程序中,一般也只用到  二级指针,三个星号不常见,更别说四个星号了.    指针的指针需要用到指针的地址.        char c='A';        char *p=&c;        char **cp=&p

C++基类指针指向的派生类对象内存的释放

C++由于基类指针可以指向不同的派生类对象,因此当赋予基类指针不同的地址时,要注意之前的派生类对象的内存释放. int main(){ Parent* ptr = new Child1; Child2 myChild2; Child3 myChild3; ptr->show(); delete ptr; //位置1 ptr = &myChild2; ptr->show(); delete ptr; //位置2 ptr = &myChild3; ptr->show(); d