阅读在标题为"Faces of " 的部分中编写一致的惯用JavaScript的原则,this
它表明this
JavaScript 中的别名"非常容易出错".
我个人尝试尽可能使用_.bind()
(或类似的东西),但有人知道为什么混叠this
是如此容易出错?
我是Javascript的新手,只是想确保我理解它是如何处理this
关键字的,因为......好吧,它看起来很混乱.我已经在StackOverflow上查看了类似的问题,并希望确保我没有向前推进错误的想法.
所以我正在定义一个类似的类,并希望处理构造函数中收到的每个点.
function Curve(ptList) {
this.pts = [];
if(ptList.length > 2) {
// I want to call "addPoint" for every item in ptList right here
}
}
Curve.prototype.addPoint = function(p) {
this.pts.push(p);
/* some more processing here */
}
Run Code Online (Sandbox Code Playgroud)
所以,最初我以为我可以做到:
ptList.forEach(this.addPoint);
Run Code Online (Sandbox Code Playgroud)
但我不能,因为这仅仅是一个指针传递给所述原型函数,这意味着this
在addPoint
指全局对象.
然后我尝试了:
ptList.forEach(function(p) { this.addPoint(p); });
Run Code Online (Sandbox Code Playgroud)
但我不能,因为this
只要我输入内部函数(它不再引用Curve
正在构造的对象)就引用全局范围,因此addPoint
未定义.
解决这个问题的方法是创建一个变量,该变量引用this
一个范围,我仍然可以在子函数中与之交谈:
var _this = this;
ptList.forEach(function(p) { _this.addPoint(p); });
Run Code Online (Sandbox Code Playgroud)
这最终有效(但对于没有JS经验的人来说看起来很奇怪).但后来我发现了这个bind
函数,它让我不能定义一个简单的函数包装器:
ptList.forEach(this.addPoint.bind(this));
Run Code Online (Sandbox Code Playgroud)
最后,这似乎是最好,最简洁的方法,甚至认为它看起来很傻.没有这个bind
功能,addPoint
就不知道它被调用了哪个对象,没有第一个 …
我试图创建一个展示一个例子,为什么这个成语var that = this
是必要的(例如,作为描述在这里).
所以,我从一个错误的代码示例开始,该代码无法正确绑定this
.但是,我写的代码给了我一些意想不到的结果(在另一个方向):
message = "message in global scope";
// the below erroneous code aims to demonstrate why we need
// the "var that = this" idiom to capture the "this" lexical scope
var createLoggingFunctionWrongWay = function () {
return function () {
console.log(this.message);
};
};
// the below *does* print "message in global scope"
// i.e. fails in the way I expected
createLoggingFunctionWrongWay.call({message:"message"})();
// I was expecting the below to also …
Run Code Online (Sandbox Code Playgroud) function LolClass(){
this.init = function(){
button_a.bind("tap", function(){
this.refreshFields(); // doesn't work
//refreshFields(); // doesn't work either
});
}
this.refreshFields = function(){
alert("LOL");
}
this.dummy = function(){
this.refreshFields(); // W O R K S!
}
}
Run Code Online (Sandbox Code Playgroud)
当我点击button_a时,我得到一个引用错误,因为没有"找到"refreshFields方法.
未捕获的ReferenceError:未在file:///android_asset/www/src/pages/main.js中定义refreshFields:70
但是如果我在其他地方调用该方法而不是那个tap侦听器,它就可以了.
我完全确定this
tap tapner函数内部引用了事件目标button_a.
我的问题是:最好的(oo)解决方案是什么?
我想知道并理解这个和那个之间的不同,以及当我必须使用它时.我准备了许多帖子和许多教程,但我还不明白
这是我的班级
function Container(param) {
function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
}
this.member = param;
var secret = 3;
var that = this;
this.service = function () {
console.log(this.member); // foo
console.log(that.member); // foo
return dec() ? that.member : null;
};
}
Run Code Online (Sandbox Code Playgroud)
新
var myContainer = new Container('foo');
myContainer.service()
Run Code Online (Sandbox Code Playgroud)
调用myContainer.service()
将在前三次调用时返回'abc'.之后,它将返回null
为什么我要做var that = this
?
我在骨干视图中有以下代码:
var BookView = Backbone.View.extend({
initialize: function() {
this.render();
},
render: function() {
this.model.fetch({
success : function(model, resp, opt) {
alert(this.$el.html() ); //THIS ONE DOESN'T WORK?
}
});
alert(this.$el.html() ); // THIS ONE WORKS FINE
}
});
Run Code Online (Sandbox Code Playgroud)
我有两个alert(this.$el.html() );
电话,一个在提取之外,一个在里面.但由于某种原因,fetch调用之外的那个工作,但fetch调用内的一个返回错误:
Uncaught TypeError: Cannot read property 'html' of undefined
如何传递this
给分配给我的事件的函数window.onscroll
?
我试图myFunction()
在满足特定条件时触发。我需要检查这个情况onscroll
init() {
window.onscroll = function() {
if(this.currentItemCount() > this.totalElements){
this.totalElements = this.currentItemCount();
this.myFunction();
}
};
}
Run Code Online (Sandbox Code Playgroud)
this.currentItemCount()
但是我收到一个不是函数的错误。我知道我需要传递this
给window.onscroll
但我无法弄清楚正确的语法。
javascript ×7
this ×2
backbone.js ×1
bind ×1
ecmascript-6 ×1
foreach ×1
jquery ×1
node.js ×1
oop ×1
scope ×1