javascript – 如何在我的对象范围之外调用’this’?

前端之家收集整理的这篇文章主要介绍了javascript – 如何在我的对象范围之外调用’this’?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我为网站开发了某种Jcrop初始化,我设法创建了自己的命名空间.我的问题是关于这个关键字.每次我必须在任何回调函数中访问我的基础对象“aps”时,我必须将它包装在一个变量中(我选择了这个单词).有没有更好的方法呢?例如,我可以使用call或apply方法吗?这只是一个命名空间,所以我可以使用简单的aps.methodName但是为了这个例子,请不要介意.这是我的源代码
  1. var aps;
  2.  
  3. $(function(){
  4. aps = function(){
  5.  
  6. // private
  7. // variables
  8.  
  9. var bgColor = '#f5f5f5';
  10. var threshold = 370;
  11. var threshold_width = 800;
  12.  
  13. return {
  14. tmpl : $('#jcrop-template').html(),upl_cont : {},form : {},logo_img : new Image(),jcrop_api : null,scaled_logo_url : '',image_filename : '',original_image_filename : '',mime : '',trueSize : '',jcrop_init : function (oiFrameRes){
  15. $('#logo_upload_form').find('img').hide();
  16. this.scaled_logo_url = oiFrameRes.image_url;
  17. this.logo_url = oiFrameRes.original_image_url;
  18. this.original_image_filename = oiFrameRes.original_image_filename;
  19. this.image_filename = oiFrameRes.image_filename;
  20. this.mime = oiFrameRes.mime;
  21. this.upl_cont = $('#faceBox div#upload-container-d');
  22. this.logo_img = new Image();
  23. this.logo_img.that = this;
  24. this.logo_img.name = 'logo';
  25. this.logo_img.onload = function(){
  26. this.true_width=this.width;
  27. this.true_height=this.height;
  28. this.that.resize_image();
  29. this.that.resize_faceBox();
  30. this.that.display_image();
  31. }
  32. this.logo_img.src = this.logo_url;
  33. },resize_image : function(){
  34. this.trueSize = '';
  35. if(typeof (this.oSettings.trueSize)!=='undefined') delete(this.oSettings.trueSize);
  36. if (this.logo_img.width > threshold){
  37. if (this.logo_img.width > threshold_width){
  38. this.trueSize = [ this.logo_img.width,this.logo_img.height ];
  39. this.logo_img.height = this.logo_img.height / (this.logo_img.width / threshold_width);
  40. this.logo_img.width = threshold_width;
  41. }
  42. }
  43. },resize_faceBox : function(){
  44. var width = (this.logo_img.width > threshold) ? this.logo_img.width : threshold ;
  45. $('#faceBox').css({
  46. left : $(window).width() / 2 - width / 2
  47. }).
  48. find('div.change-size').css({'width': width+30});
  49. },display_image : function (){
  50. if (this.jcrop_api === null) {
  51. $logo_img = $(this.logo_img).css({'display':'block','margin-left':'auto','margin-right':'auto'})
  52. if (this.upl_cont.find('#logo-container-d>img').length > 0){
  53. if (this.upl_cont.find('#logo-container-d>img').attr('src').length > 0){
  54. this.upl_cont.find('#logo-container-d').empty().append($logo_img);
  55. }
  56. }
  57. else {
  58. this.upl_cont.append(this.tmpl).find('#logo-container-d').append($logo_img);
  59. }
  60.  
  61. var that = this;
  62. if (typeof (this.upl_cont.find('#jcrop-menu1 a').data('events')) === 'undefined'){
  63. this.upl_cont.find('#jcrop-menu1 a').click(function(){
  64. if (this.href.indexOf('#crop')>-1){
  65. $(this).closest('div').hide();
  66. that.upl_cont.find('#jcrop-menu2').show();
  67. that.setup_crop();
  68. }
  69. if (this.href.indexOf('#close')>-1){
  70. manageIframeResponse();
  71. }
  72. location.hash = '';
  73. return false;
  74. });
  75. }
  76. }
  77. else {
  78. this.reset();
  79. }
  80. },reset : function(){
  81. $('#jcrop-menu2',this.upl_cont).find('a').unbind('click').end().hide();
  82. $('#jcrop-coords-f',this.upl_cont).find('input[type="text"]').each(function(){this.value="";}).end().hide();
  83. $('#jcrop-menu1',this.upl_cont).find('a').unbind('click').end().show();
  84. this.jcrop_api.destroy();
  85. this.jcrop_api=null;
  86. this.display_image();
  87. },send_form : function (){
  88. var sPost = $(this.form).find('input[name="image_filename"]').val(this.image_filename).end()
  89. .find('input[name="original_image_filename"]').val(this.original_image_filename).end()
  90. .find('input[name="mime"]').val(this.mime).end()
  91. .find('input[name="user_url"]').val($('#logo_upload_base_url').val()).end()
  92. .find('input[name="user_key"]').val($('#logo_upload_user_key').val()).end()
  93. .serialize();
  94.  
  95. $.ajax({
  96. url:'iframe_upload.PHP',type:'POST',data: sPost,success : function(response){
  97. manageIframeResponse();
  98. },dataType : 'json'
  99. });
  100. },setup_crop : function (){
  101.  
  102. var that = this;
  103. if (this.jcrop_api === null) {
  104. this.form = this.upl_cont.find('form#jcrop-coords-f').get(0);
  105. this.upl_cont.find('#jcrop-menu2>a').click(function(){ that.send_form();return false; });
  106. this.updateForm = function (){
  107. var c = arguments[0];
  108. that.form.x1.value=c.x;
  109. that.form.x2.value=c.x2;
  110. that.form.y1.value=c.y;
  111. that.form.y2.value=c.y2;
  112. that.form.h.value=c.h;
  113. that.form.w.value=c.w;
  114. }
  115.  
  116. this.oSettings.onSelect = this.updateForm;
  117. if (typeof (this.trueSize) !== 'string' && $.isArray(this.trueSize)){
  118. $.extend(this.oSettings,{'trueSize':this.trueSize});
  119. }
  120. $('#faceBox #logo-container-d>img').Jcrop( this.oSettings,function(){
  121.  
  122. that.jcrop_api = this;
  123. var _x1 = (that.logo_img.true_width*0.1).toFixed();
  124. var _y1 = (that.logo_img.true_height*0.1).toFixed();
  125. var _x2 = (that.logo_img.true_width*0.9).toFixed();
  126. var _y2 = (that.logo_img.true_height*0.9).toFixed();
  127. that.jcrop_api.setSelect([0,that.logo_img.true_width,that.logo_img.true_height]);
  128. that.jcrop_api.animateTo([_x1,_y1,_x2,_y2]);
  129. });
  130. }
  131. },updateForm : function (){},oSettings : {
  132. onSelect:'',onChange:'',keySupport: false,bgColor:bgColor,aspectRatio:1,minSize:[0,0]
  133. }
  134. }
  135. }();
  136.  
  137. $(document).bind('afterClose.faceBox',function() {
  138. if (aps.jcrop_api !=null) {
  139. aps.jcrop_api.destroy();
  140. aps.jcrop_api=null;
  141. }
  142. });
  143. });

解决方法

无论何时使用函数调用*调用函数,此值都将设置为全局变量(或在严格模式下未定义) – 即使从方法调用函数也是如此.道格拉斯·克罗克福德实际上已将此描述为该语言的一个缺陷.

将此值保存到函数可以访问的变量中是处理此问题的标准方法.

如果您真的想控制回调中的内容,可以使用apply或call.两者都将您想要设置的第一个参数作为第一个参数.不同之处在于apply期望所有函数的参数作为数组传递,而call期望您单独列出它们.

因此,如果在你的ajax回调中,你想调用manageIframeResponse,请传递ajax调用的响应(我知道你的例子没有传递响应,我只是说明你将如何做),并将其值设为与当前对象相同,您可以这样做:

  1. var self = this;
  2. $.ajax({
  3. success : function(response){
  4. manageIframeResponse.apply(self,[response]); //<--- apply wants your arguments in array form
  5. }
  6. });

或者,由于您的参数尚未采用数组形式,因此您可以更简单地使用调用

  1. var self = this;
  2. $.ajax({
  3. success : function(response){
  4. manageIframeResponse.call(self,response); //<---call takes the arguments listed out one at a time
  5. }
  6. });

*
有不同的方法调用函数.

函数调用意味着您只是调用恰好位于当前范围内的函数

  1. foo() //inside foo,this will be the global object (or undefined in strict mode)

方法调用意味着您正在调用附加到对象的函数

  1. myObj.foo() //inside foo,this will be myObj

这里有一个例子,如果你不小心,这会让你感到沮丧.

  1. function objCreator() {
  2. var y = "There";
  3.  
  4. function privateFunc() {
  5. alert(y); //alerts There as expected
  6. alert(this.someField); //undefined: whoops - this is the global object,} //so there's no someField
  7.  
  8. return {
  9. x: "Hi",someField: "blah",foo: function () {
  10. alert(this.x);
  11. privateFunc();
  12. }
  13. };
  14. }

猜你在找的JavaScript相关文章