回答編集履歴

4

「型の判定」節を追記

2017/08/09 02:51

投稿

think49
think49

スコア18166

test CHANGED
@@ -532,6 +532,70 @@
532
532
 
533
533
 
534
534
 
535
+ ### 型の判定
536
+
537
+
538
+
539
+ Object 型を期待する変数は Object 型もしくは Null 型を代入すべき変数です。
540
+
541
+
542
+
543
+ ```HTML
544
+
545
+ <script>
546
+
547
+ var a = 1;
548
+
549
+ </script>
550
+
551
+ <script>
552
+
553
+ var a = a || {};
554
+
555
+ console.log(a); // 1
556
+
557
+ </script>
558
+
559
+ ```
560
+
561
+
562
+
563
+ 期待に反して、変数 `a` には Number 型の値が代入されています。
564
+
565
+ この状況は、次のコードで改善されます。
566
+
567
+
568
+
569
+ ```HTML
570
+
571
+ <script>
572
+
573
+ var a = 1;
574
+
575
+ </script>
576
+
577
+ <script>
578
+
579
+ if (Object(a) !== a) {
580
+
581
+ throw new TypeError(a + ' is not a object'); // TypeError: 1 is not a object
582
+
583
+ }
584
+
585
+ var a = {};
586
+
587
+ console.log(a);
588
+
589
+ </script>
590
+
591
+ ```
592
+
593
+
594
+
595
+ `TypeError` を発生させる事で Object 型以外の値が代入されている事が分かります。
596
+
597
+
598
+
535
599
  ### まとめ
536
600
 
537
601
 
@@ -558,6 +622,12 @@
558
622
 
559
623
 
560
624
 
625
+ ただし、「型の判定」節で触れている通り、`var a = a || {};` は Object 型以外の値が代入するケースを排除できない問題があります。
626
+
627
+ 判定条件が緩い為、`Object()` で正しく判定するコードがより好ましいといえます。
628
+
629
+
630
+
561
631
  ### 更新履歴
562
632
 
563
633
 
@@ -566,6 +636,8 @@
566
636
 
567
637
  - 2017/08/09 10:56 const による再代入禁止のコード事例が再定義禁止になっていた為、再代入禁止のコードに修正
568
638
 
639
+ - 2017/08/09 11:51 「型の判定」節を追記
640
+
569
641
 
570
642
 
571
643
  Re: LanHma さん

3

const による再代入禁止のコード事例が再定義禁止になっていた為、再代入禁止のコードに修正

2017/08/09 02:51

投稿

think49
think49

スコア18166

test CHANGED
@@ -482,17 +482,53 @@
482
482
 
483
483
  'use strict';
484
484
 
485
- var a = {bar: 2}; // SyntaxError: Identifier 'a' has already been declared
485
+ a = {bar: 2}; // TypeError: Assignment to constant variable. (再代入禁止)
486
-
486
+
487
- </script>
487
+ </script>
488
+
488
-
489
+ <script>
490
+
491
+ 'use strict';
492
+
493
+ var a = {bar: 2}; // SyntaxError: Identifier 'a' has already been declared (再定義禁止)
494
+
495
+ </script>
496
+
489
- ```
497
+ ```
498
+
499
+
500
+
490
-
501
+ `TypeError` が `const` による再代入禁止、`SyntaxError` は再定義禁止による規定によるものです。
502
+
491
-
503
+ `let` も再定義禁止の為、`var`, `let`, `const` による同じ名前の変数宣言を防ぐ事が可能です。
492
-
504
+
505
+
506
+
493
- なお、`const` は再代入は禁止されていますが、プロパティの書き換えは許容されている為、複数のスクリプト間で同じオブジェクトを共有する事は可能です。
507
+ なお、`const` は再代入は禁止されていますが、プロパティの書き換えは許容されている為、複数のスクリプト間で同じオブジェクトを共有する事は出来ます。
508
+
509
+
510
+
494
-
511
+ ```HTML
512
+
495
-
513
+ <script>
514
+
515
+ 'use strict';
516
+
517
+ const a = {foo: 1};
518
+
519
+ </script>
520
+
521
+ <script>
522
+
523
+ 'use strict';
524
+
525
+ a.bar = 2; // プロパティの書き換えは出来る
526
+
527
+ console.log(a); // {foo: 1, bar: 2}
528
+
529
+ </script>
530
+
531
+ ```
496
532
 
497
533
 
498
534
 
@@ -528,6 +564,8 @@
528
564
 
529
565
  - 2017/08/05 00:58 「Object.defineProperty() と const」を追記
530
566
 
567
+ - 2017/08/09 10:56 const による再代入禁止のコード事例が再定義禁止になっていた為、再代入禁止のコードに修正
568
+
531
569
 
532
570
 
533
571
  Re: LanHma さん

2

「Object\.defineProperty\(\) と const」を追記

2017/08/09 01:56

投稿

think49
think49

スコア18166

test CHANGED
@@ -412,17 +412,103 @@
412
412
 
413
413
 
414
414
 
415
+ ### Object.defineProperty() と const
416
+
417
+
418
+
419
+ ES3 への配慮が不要なら、グローバル名前空間の衝突対策として、次の2つが有力な選択肢となります。
420
+
421
+
422
+
423
+ - ES5 実装が対象なら、`Object.defineProperty()` を使う
424
+
425
+ - ES6 実装が対象なら、`let` または `const` を使う
426
+
427
+
428
+
429
+ `Object.defineProperty()` の有効性は説明済みなので省くとして、ES6 では特に `const` が衝突検出器として有力です。
430
+
431
+ `Object.defineProperty()` による上書き禁止のコードでは上書きはできないものの、上書きを試みたタイミングでは何も発生しない静かなコードでした。
432
+
433
+
434
+
435
+ ```HTML
436
+
437
+ <script>
438
+
439
+ Object.defineProperty(this, 'a', {
440
+
441
+ writable: false, // 上書き禁止
442
+
443
+ enumerable: false,
444
+
445
+ configurable: true,
446
+
447
+ value: {foo: 1}
448
+
449
+ });
450
+
451
+ </script>
452
+
453
+ <script>
454
+
455
+ var a = {bar: 2, piyo: function () { return this.bar; }}; // 上書き禁止だが、ここではエラーが発生しない
456
+
457
+ console.log(a.bar); // undefined (ここでもエラーが発生しない)
458
+
459
+ console.log(a.piyo()); // TypeError: a.piyo is not a function
460
+
461
+ </script>
462
+
463
+ ```
464
+
465
+
466
+
467
+ `const` は**再代入を禁止する**為、上書きする事が出来ません。
468
+
469
+
470
+
471
+ ```HTML
472
+
473
+ <script>
474
+
475
+ 'use strict';
476
+
477
+ const a = {foo: 1};
478
+
479
+ </script>
480
+
481
+ <script>
482
+
483
+ 'use strict';
484
+
485
+ var a = {bar: 2}; // SyntaxError: Identifier 'a' has already been declared
486
+
487
+ </script>
488
+
489
+ ```
490
+
491
+
492
+
493
+ なお、`const` は再代入は禁止されていますが、プロパティの書き換えは許容されている為、複数のスクリプト間で同じオブジェクトを共有する事は可能です。
494
+
495
+
496
+
497
+
498
+
415
499
  ### まとめ
416
500
 
417
501
 
418
502
 
419
- `var` 宣言を使ったコードを次の2つのケースで有効だと思います。
503
+ まとめると、次のようになると思います。
420
-
421
-
422
-
423
- - ES3 実装に対応する必要があり、Polyfill を書く場合
504
+
424
-
505
+
506
+
425
- - ES3 実装応する必要があり、複数の自作ライブラリ間でオブジェクトを共有する場合
507
+ - ES3 実装象ならPolyfill もしくは複数の自作ライブラリ間でオブジェクトを共有する場合に `var` 宣言を使う
508
+
509
+ - ES5 実装が対象なら、`Object.defineProperty()` を使う
510
+
511
+ - ES6 実装が対象なら、`let` または `const` を使う
426
512
 
427
513
 
428
514
 
@@ -430,12 +516,18 @@
430
516
 
431
517
 
432
518
 
433
-
434
-
435
519
  - [Internet Explorer のサポートポリシーが変わります - MSBC](https://www.microsoft.com/japan/msbc/Express/ie_support/)
436
520
 
437
521
  - [Windows Vista のサポートは終了しました - Windows Help](https://support.microsoft.com/ja-jp/help/22882/windows-vista-end-of-support)
438
522
 
439
523
 
440
524
 
525
+ ### 更新履歴
526
+
527
+
528
+
529
+ - 2017/08/05 00:58 「Object.defineProperty() と const」を追記
530
+
531
+
532
+
441
533
  Re: LanHma さん

1

2017/04/11\(Windows Vista のサポート終了日\)

2017/08/04 15:58

投稿

think49
think49

スコア18166

test CHANGED
@@ -426,7 +426,15 @@
426
426
 
427
427
 
428
428
 
429
- 最も、MS IE10- のサポートを打ち切った今では、ES3 に配慮する場面は少ないと思います。
429
+ 最も、Microsoft は2017/04/11(Windows Vista のサポート終了日)に IE10- のサポートを終了している為、ES3 に配慮する場面は少ないと思います。
430
+
431
+
432
+
433
+
434
+
435
+ - [Internet Explorer のサポートポリシーが変わります - MSBC](https://www.microsoft.com/japan/msbc/Express/ie_support/)
436
+
437
+ - [Windows Vista のサポートは終了しました - Windows Help](https://support.microsoft.com/ja-jp/help/22882/windows-vista-end-of-support)
430
438
 
431
439
 
432
440