---
# System prepended metadata

title: '[Appendix A: Mixed Environment JavaScript](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/types%20%26%20grammar/apA.md)'
tags: [JS]

---

###### tags: `JS`
[Appendix A: Mixed Environment JavaScript](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/types%20%26%20grammar/apA.md)
===

# Annex B (ECMAScript)

[Standard ECMA-262](http://www.ecma-international.org/publications/standards/Ecma-262.htm)

[ECMAScript® 2019 Language Specification](http://www.ecma-international.org/ecma-262/10.0/index.html#sec-additional-ecmascript-features-for-web-browsers)

- 不在 ECMAScript 的核心之中，不應該假設這些功能都是有的，不鼓勵自己去實作，除非原本就是 web browser 的一部份
- `window.escape()` 與 `window.unescape()`
- OctalDigit
- `String.prototype.substr()`改用 `String.prototype.substring()`  // [MDN](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String/substr)

# Host Objects

- JS 可以跑在不同的環境，如 `browser` `node` `Rhino` [Rhino是什麼](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino)
- 不同環境會有其特殊的用法，如 `HTMLDivElement`
- 相同的語法在不同的環境會有不一樣的行為 `console.log()`
```javascript=
var a = document.createElement("div");

typeof a; // "object"
a.toString(); // "[object HTMLDivElement]"
Object.prototype.toString.call(a); // "[object HTMLDivElement]"

a.tagName; // "DIV"
```


# Global DOM Variables

- 在 html 設 id 的話會有一個全域變數產生

```javascript=
foo; // ReferenceError 
var a = document.createElement("div");
a.id = foo;
document.getElementByTagName("body").appendChild(a);
foo; // <div id="foo"></div>
```

# Native Prototypes

- 不要在 `prototype` 加東西
```javascript=
if (!Array.prototype.push) {
	// Netscape 4 doesn't have Array.push
	Array.prototype.push = function(item) {
		this[this.length] = item;
	};
}
```
- 如果真的要的話，請寫檢查或寫測試
- `shim` 相容性測試
```javascript=
// don't trust Array.prototype.push
(function(){
	if (Array.prototype.push) {
		var a = [];
		a.push(1,2);
		if (a[0] === 1 && a[1] === 2) {
			// tests passed, safe to use!
			return;
		}
	}

	throw Error(
		"Array#push() is missing/broken!"
	);
})();
```
- `polyfill` 檢查功能存在
```javascript=
if (!Array.prototype.foobar) {
	// silly, silly
	Array.prototype.foobar = function() {
		this.push( "foo", "bar" );
	};
}
```
- 沒有 100% 安全的做法

# <script>

- 分開寫的話 `hoisting` 無作用
```htmlmixed=
// 不行
<script>foo();</script>

<script>
  function foo() { .. }
</script>
```
```htmlmixed=
// 可以
<script>
  foo();
  function foo() { .. }
</script>
```
```htmlmixed=
// 可以
<script>
  function foo() { .. }
</script>

<script>foo();</script>
```
- 要小心在 `<script>` 中不要再寫到 `<script>` 否則會解析錯誤
```htmlmixed=
// 不行
<script>
  var code = "<script>alert( 'Hello World' )</script>";
</script>
```
```htmlmixed=
// 可以
<script>
  var code = "<script>alert( 'Hello World' )</sc" + "ript>";
</script>
```
- 不要使用 HTML 或 XHTML 註解的寫法
```htmlmixed=
<script>
<!--
alert( "Hello" );
//-->
</script>

<script>
<!--//--><![CDATA[//><!--
alert( "World" );
//--><!]]>
</script>
```

# Reserved Words

[Lexical grammar](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords)

# Implementation Limits

- 小心值的限制

```javascript=
function addAll() {
    var sum = 0;
    for (var i=0; i<arguments.length; i++) {
        sum += arguments[i];
    }
		return sum;
}

var nums = [];
for (var j=1; j< 100000; j++) { nums.push(j);}

addAll(2, 4, 5);
addAll.apply(null, nums);
```
## 補充
[RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax](https://tools.ietf.org/html/rfc3986#section-2.1)
[es-shims/es5-shim: ECMAScript 5 compatibility shims for legacy (and modern) JavaScript engines](https://github.com/es-shims/es5-shim/)