简体   繁体   English

无法访问函数外部的变量

[英]Can't access variable outside function

I have the following JS: 我有以下JS:

Meteor.startup(function () {
  map = L.map('map_canvas').locate({setView: true, maxZoom: 21});
  L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
  }).addTo(map);
    bounds = {};    
    map.on('locationfound', function(e){ 
      bounds.bottomLeftLat = map.getBounds()._southWest.lat;
      bounds.bottomLeftLng = map.getBounds()._southWest.lng;
      bounds.topRightLat = map.getBounds()._northEast.lat;
      bounds.topRightLng = map.getBounds()._northEast.lng;
      console.log(bounds);
    });
  console.log('outside function: '+bounds);
});

My first console.log outputs correctly the 4 object properties with their values in the console, but the outside function log outputs an empty object, and when I try to access bounds outside of Meteor.startup then it's not even defined. 我的第一个console.log在控制台中正确输出了4个对象属性及其值,但是外部函数日志输出了一个空对象,当我尝试访问Meteor.startup之外的界限时,甚至没有定义它。 I understand that functions limit the scope of variables but if bounds is defined outside the anonymous function, without 'var', isn't it considered to be a global? 我知道函数会限制变量的范围,但是如果界限是在匿名函数之外定义的,且没有'var',那么它是否被认为是全局变量?

  1. Why can I access 'map' but not 'bounds' outside of Meteor.startup? 为什么我可以在Meteor.startup之外访问“地图”而不访问“边界”?
  2. How could I rewrite this code by following more smart patterns (module?) so that I can both make bounds available in other parts of the script and successfully add the four properties as I am attempting? 我如何通过遵循更多的智能模式(模块?)来重写此代码,以便既可以使边界在脚本的其他部分中可用,又可以在尝试添加成功时添加这四个属性?

edit the event is fired - after manually firing it, I still get an empty object: 编辑事件被触发-手动触发事件后,我仍然得到一个空对象:

map.fire("locationfound");
Object {type: "locationfound", target: e, bottomLeftLat: 50.05008477838258, bottomLeftLng: 0.384521484375, topRightLat: 51.63847621195153…}
 MainClient.js:12
e {options: Object, _container: div#map_canvas.leaflet-container leaflet-fade-anim, _panes: Object, _mapPane: div.leaflet-map-pane, _tilePane: div.leaflet-tile-pane…}
bounds
Object {}

It is seeing bounds but your console.log happens before the callback on the locationfound event, so its still empty when you're trying to access it. 它正在看到bounds但是您的console.log发生在locationfound事件的回调之前,因此当您尝试访问它时,它仍然为空。

All of your initialization will happen the first time a locationfound event fires, and a log at that point will show the results you expect. 您的所有初始化都会在locationfound事件首次触发时发生,并且此时的日志将显示您期望的结果。

A few thoughts. 一些想法。

  1. In general declaring variables without var is frowned upon. 通常,声明不带var变量是不受欢迎的。 If you want to access it globally, declare it with var in a global context, or (ideally) use a namespace variable and declare all your global variables as properties of that. 如果要全局访问它,请在全局上下文中用var声明,或(理想情况下)使用名称空间变量并将所有全局变量声明为其属性。

  2. If you want to access bounds after it has been modified, you can put the call to the functions you want to run inside the callback 如果要在修改边界之后访问边界,可以将调用置于要在回调内部运行的函数

Update to clarify your code's behavior 更新以阐明代码的行为

Here is how your code executes. 这是代码的执行方式。

//This is the startup function for meteor.  It is passed a function, 
//and executes that function when the code starts up
Meteor.startup(function () {
    //You're now inside the function you passed to startup, and you initialize map
    //...
    bounds = {};    
    //here you call the `on` function on map, and bind a 
    //callback function to the locationfound event
    map.on('locationfound', function(e){ 
      //This code is inside the callback and will be executed when the event occurs 

      // code initializing bounds

      console.log(bounds); //this will show the full definition of bounds
      //callback ends here
    });
  //this is outside the callback but still inside startup, 
  //and occurs immediately after the call to map.on
  console.log('outside function: '+bounds); //bounds is still empty
}); //end the startup function

It seems like the key thing you need to understand is the on function. 似乎您需要了解的关键是on函数。 It is a leaflet function that takes 2 arguments, an event type and a callback function, and binds the callback function to the event. 它是一个小叶函数,它接受2个参数,一个事件类型和一个回调函数,并将该回调函数绑定到该事件。 The callback function then runs when the event occurs, not before. 然后,在事件发生时(而不是之前)运行回调函数。 The callback does not run immediately. 回调不会立即运行。 Instead the code continues executing, and will execute the callback code when the event occurs. 而是代码继续执行,并在事件发生时执行回调代码。

Documentation for on 文档on

This is what called javascript event loop The code outside the 'map' can access to the bounds var but you try to access it immediately after you defince the locationfound event of the map - the bounds only initialise when this event will occure - so what are you getting in the console is just an empty object that you defined before "bounds = "{}" 这就是所谓的javascript事件循环 。“地图”外部的代码可以访问bounds var,但是您在定义地图的locationfound事件后立即尝试访问它-边界仅在此事件发生时才初始化-那么您进入控制台只是在“ bounds =” {}“之前定义的空对象

What you did is correct - you can access the bounds only inside the locationfound event cause only then you initialize it 您所做的是正确的-您只能在locationfound事件原因内访问边界,然后才对其进行初始化

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM