这个问题在这里已经有了答案:
How does the "this" keyword work?
(21 个回答)
6年前关闭。
我正在尝试了解 this ,这让我有点困惑:
var randomFunction = function(callback) {
var data = 10;
callback(data);
};
var obj = {
initialData: 20,
sumData: function(data) {
var sum = this.initialData + data;
console.log(sum);
},
prepareRandomFunction: function() {
randomFunction(this.sumData.bind(this));
}
};
obj.prepareRandomFunction();
是 this旨在将自身设置在代码中首次呈现的位置?obj并将函数绑定(bind)到 obj ,但由于 this正在作为回调函数传递,是什么阻止它被设置为 randomFunction (即是什么阻止它从字面上传递“this.sumData.bind(this)”,以便 this 在从那里被调用时设置为 randomFunction)?this在我将其定义为我的 randomFunction 的参数的地方被设置打电话,而不是在哪里callback在 randomFunction 内被调用.this.sumData.bind(this)与 callback(data)我目前拥有的我认为我会得到不同的结果。是不是因为callback是对 this.sumData.bind(this) 的引用它是什么时候第一次定义的(在哪里 this 是 obj )?this执行时设置。它不会作为参数传递,以便稍后在该参数被调用时进行设置。
最佳答案
this在函数调用内部根据函数的调用方式设置。 this主要有六种方式设置。
foo() , this设置为全局对象(浏览器中的 window 或 nodejs 中的 global)或 undefined (在 JavaScript 的严格模式下)。obj.foo()其中方法foo是使用 function 的普通方法声明关键字或对 class 使用常规方法声明语法,然后 this设置为 obj函数内部。.apply()或 .call()被使用,然后 this根据传递给 .apply() 的内容设置或 .call() .例如,你可以做 foo.call(myObj)并导致 this设置为 myObj内部 foo()对于那个特定的函数调用。new 调用函数如 new foo() ,然后创建一个新对象和构造函数 foo用 this 调用设置为新创建的对象。.bind()从内部使用 .apply() 的调用返回一个新的 stub 函数设置 this传递给 .bind() 的指针.仅供引用,这并不是真正的不同情况,因为 .bind()可以通过 .apply() 实现.this到它。因此,无论在其他地方如何调用该函数(使用之前的任何调用方式),this value 将由解释器设置为值 this在定义函数时有。这与所有其他函数调用完全不同。this 的值。将在调用回调时。您必须查阅文档或调用函数的代码或自行测试以确定是什么 this将在回调中设置为。this 设置一个新值。 .并且,设置哪个值取决于函数的调用方式。 obj.method()因此不会有 this 的正确值设置它。您可以使用 .bind()解决这个问题。this 调用也很有用。由调用回调函数的基础设施设置。在内部,他们都使用 .call()或 .apply()所以这不是一个新规则,而是需要注意的事情。回调函数的“契约”可能包括它如何设置 this 的值。 .如果没有明确设置this的值,那么它将根据规则 #1 进行设置。this .这是维护词法 this 的数组函数的示例from MDN :function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| properly refers to the person object
}, 1000);
}
var p = new Person();
obj.prepareRandomFunction(); 示例是上面的规则 #2 所以 this将设置为 obj .randomFunction(this.sumData.bind(this)) 示例是上面的规则 #1 所以 this内部 randomFunction将设置为全局对象或 undefined (如果在严格模式下)。.bind() ,那么 this 的值回调函数内部调用时会被设置为this的值传递给 .bind()在 this.sumData.bind(this)就像上面的第 5 条规则一样。 .bind()实际上创建了一个新函数,它的工作是在设置自定义值 this 之后调用原始函数。 ..apply()或 .call()或 .bind() ,您可以创建各种有点奇怪的东西,有时甚至是非常有用的东西,而这些东西在 C++ 之类的东西中是永远无法完成的。 .您可以使用世界上的任何函数或方法,并像调用其他对象的方法一样调用它。arguments 中的项目。对象到数组中:var args = Array.prototype.slice.call(arguments, 0);
或类似:var args = [].slice.call(arguments, 0);
这需要数组的 .slice()方法并调用它,但为它提供了一个参数对象作为 this指针。 arguments对象(虽然不是实际的数组),具有足够的类似数组的功能,.slice()方法可以对其进行操作,它最终会复制 arguments items 到一个实际数组中,然后可以直接使用实际数组操作对其进行操作。这种诡计不能随意完成。如果数组 .slice()方法依赖于 arguments 上不存在的其他数组方法对象,那么这个技巧是行不通的,但因为它只依赖于 []和 .length ,其中arguments对象有,它确实有效。关于javascript - 当您将 'this' 作为参数传递时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28016664/
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)