scope查看对象方法的问题
scope Issue seeing object methods
我试着搜索了很多S.O.页面,但在不使用JQUERY的情况下,没有任何内容能完全触及顶部。。。。我正在努力坚持纯JavaScript,因为在提高我目前对JQuery的了解之前,我想学习115%。
我有一个名为ScreenResizeTool的对象,如下所示。。。
function ScreenResizeTool(currImg) {
window.addEventHandler('resize', function() {
listen(currImg);
}, true);
}
还有这样的方法。。。
ScreenResizeTool.prototype.listen = function(currImg) {
//Random Code For Resizing
};
对于一个经验丰富的JavaScript用户来说,我的问题可能是显而易见的,但我很难不把它变成一个混乱、肮脏、糟糕的OOP集。我做了各种测试来向自己展示和证明addEventHandler中的this
在绑定到窗口时会发生变化。这是我在测试前假设的,但我能够看到,一旦window.resize事件发生,侦听方法就消失了,而不是全局窗口变量的一部分。。。。
我还尝试在对象构造函数中添加this
捕获(如this.me = this
(,但它在运行后也看不到me
变量。一旦窗口接管了函数,它就不再知道me
变量的任何信息,也不再知道对我的类方法的任何引用。。。。
我知道我可以用不同的方式来区分这一点,但我在这里的目标是学习如何完全封装和使用尽可能多的干净的OOP结构,就像我刚从。NET世界,我的生活中需要它。
我也意识到,我可能会进行混乱的调用和/或存储此对象,或访问窗口变量中的方法,但这对我来说似乎是完全错误的。我应该能够完全封装此对象,并在该类结构中实现其事件和方法。
我也知道currImg变量也不会出现,但让我们从这里开始。我想,一旦我弄清楚了关于JavaScript范围的错误思路,我就可以解决currImg问题了。
我知道有1000个JavaScript程序员在等着问我这个简单的问题,但我必须知道。。。
有人想吗?绑定到DOM对象(如window
(的函数内的
this
将始终引用该对象
构造函数内部的this
将始终引用prototype
。
正如您所提到的,规避this
问题的一种常见做法是将其缓存在一个变量中,通常称为self
。现在,您希望对象的变量和属性在实例化后可用,因此您需要的是return
关键字,更具体地说,返回父对象本身。让我们把这些放在一起:
function ScreenResizeTool() {
var self = this;
// method to instantiate the code is often stored in init property
this.init = function() {
window.addEventListener('resize', function() {
self.listen(); // self will refer to the prototype, not the window!
}, true);
};
return this;
}
ScreenResizeTool.prototype.listen = function() { // Dummy function
var h = window.innerHeight, w = window.innerWidth;
console.log('Resized to ' + w + ' x ' + h + '!');
};
很简单吧?所以我们现在有了原型,但如果没有实例,原型什么都做不了。因此,我们创建了一个ScreenResizeTool
的实例,并使用其init
方法对其进行实例化:
var tool = new ScreenResizeTool();
tool.init();
// every time you resize the window now, a result will be logged!
您也可以简单地存储CCD_ 15&init
方法作为构造函数中的私有函数,并在匿名对象中返回它们:
function ScreenResizeTool() {
var listen = function() { ... };
var init = function() { ... };
// in this.init you can now simply call listen() instead of this.listen()
return {
listen: listen,
init: init
}
}
检查小提琴,并确保打开你的控制台。请注意,在这种情况下,我宁愿使用第一个函数,也不愿使用第二个函数(它的作用完全相同(,因为原型只有在您有多个实例或子类
JavaScript中this
的整个概念对初学者来说是一场噩梦,在我的代码中,我通常会尽量避免它,因为它会很快混淆并导致代码不可读(IMHO(。此外,许多刚接触JavaScript但在面向对象编程语言方面经验丰富的人试图直接进入整个this
和prototype
的内容,尽管他们实际上并不需要(例如,谷歌JS模式,如IIFE作为替代方案(。
所以看看你的原始代码:
function ScreenResizeTool(currImg) {
window.addEventHandler('resize', function() {
listen(currImg); // global function listen?
}, true);
}
ScreenResizeTool.prototype.listen = function(currImg) {
//Random Code For Resizing
};
首先,你可能指的是addEventListener
。在它的回调中,你引用了listen
,但它是一个全局变量,会将其查找为window.listen
——它不会退出。所以你可以考虑这样做:
function ScreenResizeTool(currImg) {
window.addEventHandler('resize', function() {
this.listen(currImg); // what's this?
}, true);
}
因为您想要使用ScreenResizeTool
的prototype.listen
功能。但这也不起作用,因为事件侦听器的回调函数是用不同的this
调用的,而不是用作为函数范围的this
调用的。这就是让大多数程序员感到尴尬的地方,你必须缓存this
,我看到的代码示例:
var _this = this;
var that = this;
var _self = this;
让我们只使用后者来引用事件回调中的函数:
function ScreenResizeTool(currImg) {
var _self = this;
window.addEventListener('resize', function() {
_self.listen();
}, true);
}
现在,这将实际工作并实现您想要实现的目标:调用ScreenResizeTool
的prototype.listen
函数。有关工作示例,请参阅此JSFiddle:http://jsfiddle.net/KNw6R/(检查控制台输出(
最后,这个问题与是否使用jQuery无关。这是JS的一个普遍问题。尤其是当必须处理不同的浏览器实现时,你应该使用jQuery(或另一个这样的库(来使你自己的代码干净整洁,而不是为了找出以什么方式支持什么功能而篡改多个if语句。
- 文档.编写方法问题
- 使用Ajax的问题's发送多个值的Post方法
- 在对象中添加方法时出现问题
- 简单的javascript方法问题
- Node.js-异步方法调用问题
- 尝试将变量传递到对象中时的作用域问题'的方法构造函数
- 当服务器从 http 更改为 https 时,有哪些可能的方法可以解决问题
- .attr(“href”) 的问题!解决此问题的简单方法
- 将方法分配给变量和问题
- 随机数生成器,what'我的方法/统计数据有问题吗?[JS]
- 有没有一种方法可以在IE8中解决我的Rails javascript应用程序.js的问题
- 对象中的setInterval出现问题's方法
- 包含方法和突出显示元素的问题
- 谷歌地图API v3 addDomListener方法问题
- 这种计算画布元素中非白色像素的方法有什么问题
- Javascript替换方法有什么问题
- 角度非幂等方法问题
- 将访问令牌添加到主干中的标头时出现问题:它会更改方法
- Android驱动程序的scrollTo和scrollToExact 方法的问题.方法不会滚动到所需的元素文本,而是滚动
- 在集合中引用变量时出现问题.方法在渲染函数中