問題描述
我剛剛使用 Leaflet 為網站構建地圖,并注意到添加 Tile Layer 至少可以使用兩種方法,L.TileLayer()
和 L.tileLayer()
,名稱的區別僅在于單個字符的大小寫.
但是,雖然這兩種方法返回的對象都可以添加到 L.map()
返回的地圖對象中,但 L.TileLayer()
似乎沒有 addTo()
方法,而 L.tileLayer()
返回的對象.例如.兩者都有
var map = L.map('map');var tiles = new L.TileLayer(<tileUrl>, {attribution: <tileAttrib>});map.addLayer(tiles);
和
var map = L.map('map');var tiles = new L.tileLayer(<tileUrl>, {attribution: <tileAttrib>});map.addLayer(tiles);
還有
var map = L.map('map');L.tileLayer(<tileUrl>, {attribution: <tileAttrib>}).addTo(map);
同時
var map = L.map('map');L.TileLayer(<tileUrl>, {attribution: <tileAttrib>}).addTo(map);
失敗.瀏覽 Leaflet 的文檔,似乎使用正確的方法是 L.tileLayer()
那么問題是 L.TileLayer()
的用途是什么?p>
到目前為止,這是我的代碼的完整示例,要嘗試不同的替代方案,只需取消注釋要測試的代碼并確保其他代碼已被注釋
解決方案 TL;DR:
這兩個都是有效且等價的:
var foo = L.tileLayer(arguments);var foo = new L.TileLayer(參數);
這兩個在語法上是有效的(因為 Javascript 的歷史包袱)但最終會導致錯誤:
var foo = new L.tileLayer(arguments);var foo = L.TileLayer(參數);
<塊引用>要添加一個 tilelayer,至少可以使用兩種方法,L.TileLayer()
和 L.tileLayer()
嗯,它們并不是真正的兩個方法.技術上L.TileLayer
是Object
的實例,L.tileLayer
是Function
的實例,繼承Object
的原型.并且 L
充當命名空間而不是類實例.
你看,Javascript 中的面向對象編程是奇怪.您可以使用 new
關鍵字 幾乎包含任何具有原型的對象.而 基于原型的繼承 讓大多數人難以理解精通適當";哎呀.
如今,對于 ES2015 標準和花哨的 class
關鍵字,這并不是真正的問題(我會說這是一個問題,但隱藏在語法糖層之下).但在過去,開發人員不得不求助于,比如說,類繼承的創造性解決方案 有時涉及弄亂原型鏈.
Leaflet 使用了這些方法的組合 - 作為一種不希望的副作用,L.TileLayer
變成了一個 Function
并且可以調用 L.TileLayer()
直接,這很混亂.
Leaflet 還使用了工廠函數的概念:返回類實例的函數.引用 傳單教程之一:
<塊引用>大多數 Leaflet 類都有相應的工廠函數.工廠函數與類同名,但使用 lowerCamelCase
而不是 UpperCamelCase
:
function myBoxClass(name, options) {返回新的 MyBoxClass(名稱,選項);}
這只是為了方便:它使用戶免于輸入 new
關鍵字回到 害怕 關鍵字的時代>.
但這會產生另一個不受歡迎的副作用,因為在 Javascript 中,所有 Function
都有一個原型,這意味著您可以執行類似的操作
函數 myFunction() { ... }var wtf = new myFunction();
因此,new L.tileLayer()
也是有效的語法(但在運行時失敗).
<塊引用>那么L.TileLayer()
有什么用呢?
再一次,L.TileLayer()
作為函數調用是一個不受歡迎的副作用.但是 L.TileLayer
代表一個類,因此引用它很重要,因為:
if (layer instanceof L.TileLayer)
I have just been using Leaflet to build a map for a website and noticed that to add a Tile Layer at least two methods can be used, L.TileLayer()
and L.tileLayer()
, differing in their name only by the case of a single character.
However, while the object returned by both of these methods can be added to a map object returned by L.map()
the object returned by L.TileLayer()
does not seem to have the addTo()
method whilst the object returned byL.tileLayer()
. E.g. both
var map = L.map('map');
var tiles = new L.TileLayer(<tileUrl>, {attribution: <tileAttrib>});
map.addLayer(tiles);
and
var map = L.map('map');
var tiles = new L.tileLayer(<tileUrl>, {attribution: <tileAttrib>});
map.addLayer(tiles);
as well as
var map = L.map('map');
L.tileLayer(<tileUrl>, {attribution: <tileAttrib>}).addTo(map);
whilst
var map = L.map('map');
L.TileLayer(<tileUrl>, {attribution: <tileAttrib>}).addTo(map);
fails. Browsing the documentation of Leaflet it seems the proper method to use is L.tileLayer()
so the question then is what is the use of L.TileLayer()
?
Here's a full example of my code so far, to try the different alternatives simply uncomment the one to test and make sure the others are commented
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css"
integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet.js"
integrity="sha512-tAGcCfR4Sc5ZP5ZoVz0quoZDYX5aCtEm/eu1KhSLj2c9eFrylXZknQYmxUssFaVJKvvc0dJQixhGjG2yXWiV9Q=="
crossorigin=""> </script>
</head>
<body onload="makeMap()">
<script type="text/javascript">
function makeMap() {
var tileUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var tileAttrib = 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
var map = L.map('map').setView([63,15],9);
// using tileLayer and addLayer - this works
var tiles = new L.tileLayer(tileUrl, {attribution: tileAttrib});
map.addLayer(tiles);
// using tileLayer and addTo - this works
// L.tileLayer(tileUrl, {attribution: tileAttrib}).addTo(map);
// using TileLayer and addLayer - this works
// var tiles = new L.TileLayer(tileUrl, {attribution: tileAttrib});
// map.addLayer(tiles);
// using TileLayer and addTo - this fails
// L.TileLayer(tileUrl, {attribution: tileAttrib}).addTo(map);
}
</script>
<table border=1 style="position: absolute; top: 0; bottom: 0; left: 0; right: 0; width: 100%; height: 100%;">
<tr style="height: 100%;">
<td>
<div id="map" style="width: 100%; height: 100%;"></div>
</td>
</tr>
</table>
</body>
</html>
解決方案 TL;DR:
These two are both valid and equivalent:
var foo = L.tileLayer(arguments);
var foo = new L.TileLayer(arguments);
These two are syntactically valid (because of Javascript's historical baggage) but will ultimately result in errors:
var foo = new L.tileLayer(arguments);
var foo = L.TileLayer(arguments);
to add a tilelayer at least two methods can be used, L.TileLayer()
and L.tileLayer()
Well, they're not really two methods. Technically L.TileLayer
is an instance of Object
, and L.tileLayer
is an instance of Function
, which inherits the prototype of Object
. And L
acts as a namespace rather than a class instance.
You see, Object-Oriented Programming in Javascript is weird. You can use the new
keyword with pretty much any object which has a prototype. And prototype-based inheritance is confusing to grasp to most people versed in "proper" OOP.
Nowadays, with the ES2015 standards and the fancy class
keywords this is not really a problem (I'd say it's a problem, but hidden under layers of syntactic sugar). But back in the day, developers had to resort to, let's say, creative solutions for class inheritance which sometimes involves messing with the prototype chain.
Leaflet uses a combination of such methods - and as an undesired side effect, L.TileLayer
becomes a Function
and one can call L.TileLayer()
directly and that's quite confusing.
Leaflet also uses the concept of factory functions: A function that returns an instance of a class. Quoting from one of the Leaflet tutorials:
Most Leaflet classes have a corresponding factory function. A factory function has the same name as the class, but in lowerCamelCase
instead of UpperCamelCase
:
function myBoxClass(name, options) {
return new MyBoxClass(name, options);
}
This is meant just as a convenience: it saves the user from typing the new
keyword back in an era where the new
keyword was feared.
But this creates another undesired side effect, because in Javascript all Function
s have a prototype, which means that you can do stuff like
function myFunction() { ... }
var wtf = new myFunction();
Therefore, new L.tileLayer()
is also valid syntax (but fails at runtime).
then what is the use of L.TileLayer()
?
Once again, L.TileLayer()
as a function call is an undesired side effect. But L.TileLayer
represents a class and it's important to have a reference to that, because of things like:
if (layer instanceof L.TileLayer)
這篇關于何時使用 L.TileLayer 與 L.tileLayer的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!
【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!