最近这几天在开发一个hmtl5的游戏, 但是对于js怎么使用面对对象来编程有点困惑,查了一些资料
整理如下.
js的this用法 #
-
非对象属性函数(内部函数)
var point = { x : 0, y : 0, moveTo : function(x, y) { // 内部函数 var moveX = function(x) { this.x = x;//this 绑定到了哪里? }; // 内部函数 var moveY = function(y) { this.y = y;//this 绑定到了哪里? }; moveX(x); moveY(y); } }; point.moveTo(1, 1); point.x; //==>0 point.y; //==>0 x; //==>1 y; //==>1
-
对象属性函数
var point = { x : 0, y : 0, moveTo : function(x, y) { this.x = this.x + x; this.y = this.y + y; } }; point.x; // ==> 1 point.y; // == >1 point.moveTo(1, 1)//this 绑定到当前对象,即 point 对象 point.x; // ==> 1 point.y; // == >1
其实this的用法还有很多,我为什么只列出上面两种是因为所有的this用法都可以归为这两类.
非对象属性就是这个函数不存在对象的内存空间里面的函数
对象属性就是说这个函数存在于对象内存空间的函数
这样说很绕, 抽象的来说, 把每个函数都看做是对象, 我们把这个对象point想象成一个上锁的柜子A, 每个变量名就是一把钥匙, 我们这个柜子A里面可用放很多钥匙,每个钥匙又对应着其他柜子,我们也可以放东西,但是这些东西只能是一些数字字符串什么的,这就对应着对象的这种继承性,
现在我们来看放在柜子A里面的钥匙,有一个钥匙可用开其他某一个的柜子B(相当于对象的属性的moveTo
函数),当我们就在柜子B里面使用this
时,这个this
是什么呢.
这个this就要找一个柜子, 那为什么要找一个柜子(对象呢)
这就是js语言设计的松散, 当在非严格模式下,
this
会被强制转换成一个对象, 对于例子一,因为内部函数this
并没有给他赋值(你可以把他看做一个我们找不到他的钥匙的柜子), 所以this
被强制转换成了全局的柜子(全局变量)
ps: 严格模式在函数或变量前加上 'use strict';
#
怎么解决这个问题了, 有两种方法, 不是没有赋值给this
嘛, 我们可用call来给函数内部的this
赋值,
moveX.call(this, x); // 我们把当前函数的this赋给内部函数
但是这种方法不够优美, 我们还可以直接把 this
用个变量that
给内部函数用,
var that = this;
var moveY = function(y) {
that.y = y;//this
};
这样这个this
就不会被强制转换成全局变量了, 当然你可以开启严格模式, 这样this的话就会变成undefined
, 你也不会因为你的代码问题而污染全部变量.
总结 #
js 的 this
是面对对象编程的一种体现, 但是js的this
由于有点不严格,所以有时候会出现一些令人意向不到的结果,
引用