js中对this指向的理解

牢记:this是在函数执行的时候回才明确他的执行的上线文。

1.以函数的形式调用时,this永远都是window。比如fun();相当于window.fun();

 

2.以方法的形式调用时,this是调用方法的那个对象

 

3.以构造函数的形式调用时,this是新创建的那个对象

 

4.使用call和apply调用时,this是指定的那个对象

 

先看一下下面的例子

例1

var name = "The Window";
var object = {
  name: "My Object",
  getNameFunc: function () {
    return function () {
      return this.name;
    };
  }
};
console.log(object.getNameFunc()());
//
The Window

object.getNameFunc()调用返回一个函数。再调用的时候指向window

例2 

var name = "The Window";
var object = {
  name: "My Object",
  getNameFunc: function () {
    var that = this;
    return function () {
      return that.name;
    };
  }
};
console.log(object.getNameFunc()());
// My Object

相比于上面的代码,这个是用到了闭包,相当于我们在object对象中把this保存到一个变量that中,所以打印的是Object.

例3

function Foo() {
   getName = function () { alert (1); };
   return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}

//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
//2 4 1 1 2 3 3

解读代码:一共5句话:第一句定义了一个叫Foo的函数,第二句为Foo创建了一个叫getName的静态属性,存储了一个匿名函数;第三句为Foo的原型对象新创建了一个叫getName的匿名函数。第四句定义了一个函数表达式getName的函数,第五句声明了一个叫getName的函数。

在执行之前会进行变量的提升,函数的整体提升,注意Foo函数中的getName是全局变量

考察了 js运算符的优先级 ()> . >new . 为成员访问的意思。

输出:

1 Foo.getName();访问Foo函数存储的属性, 弹出2

2 getName(); 函数表达式变量提升,函数声明整体提升,表达式的赋值在下面,会覆盖函数声明的部分, 弹出 4

3 Foo().getName(); 先执行Foo函数,然后调用Foo函数的返回值对象的getName属性函数。

Foo函数的返回值为this,这里直接执行Foo函数,所以this指向window对象;所以这里相当于执行window.getName(),注意Foo函数中的getName是全局变量,当执行Foo函数的时候会重新给getName赋值,也就是alert(4)函数,将此变量的值赋值为 function(){alert(1)}。 弹出1

4 getName();因为第三步在执行Foo函数的时候已经重新给getName赋值,所以 弹出 1

5 new Foo.getName();这里考察了js中的元素符 实际上应该是new(Foo.getName)();这里把Foo.getName函数当做了构造函数来执行,访问Foo函数存储的属性, 弹出2

6 new Foo().getName(); 这里相当于(new Foo()).getName();执行前面一部分

(new Foo()),有返回值,返回的类型为this,而this在构造函数中代表的是当前实例化对象,然后调用的是实例化对象的getName函数,(而本题中没有给实例化对象添加任何属性(因为构造函数的后面的小括号里面灭有传任何参数))所以会到当前对象的原型对象上去寻getName,所以弹出是3 。

关于构造函数的返回值:

1 没有返回值则按照其他语言一样返回实例化对象。

2 若有返回值检查返回值是否为引用类型。若是基本类型,则与无返回值相同,实际返回歧视例化对象;若是引用类型,则实际返回值为这个引用类型

7 new new Foo().getName();同第6问,弹出的为3 

 

。。。。。仅仅作为了解this。。。。

 

例4

 function A(x){
this.x = x;
}
A.prototype.x = 1;

function B(x){
this.x = x;
}
B.prototype new A();//这句意思是B的实例的原型对象为A;继承了A的原型中
的属性
var a = new A(2), b = new B(3);
delete b.x;

console.log(a.x)
console.log(b.x)

代码执行完以后,a.x和b.x的结果是什么?分别为:2,undefined

第一个输出为2,直接给构造函数A传进去一个参数(2),输出为2,没有问题。

第二个输出为undefined,delete表示的是把B上的x属性被删除了,所以会去原型链上去找,B继承A,先去A的内部找,找到了为undefined。

posted @ 2021-02-24 14:51  香香香。。。。香菜  阅读(170)  评论(0编辑  收藏  举报