# 严格模式

解释器在解释一个语句时,如果以function开头,就会理解为函数声明。 而前面加一个"!"可以让解释器理解为函数表达式,这样就可以立即调用了。

严格模式:开头写'use strict'

1、不允许给未声明的变量赋值

    name = 'LiLei';        (✖)
    var name = 'LiLei';   (✔)
1
2

2、不允许对象字面量重复属性名

!function() {
    var obj = { x: 1, x: 2 };
    console.log(obj.x);  //2
}();

!function() {
    'use strict';
    var obj = { x: 1, x: 2 };
    console.log(obj.x);  // IE10+报错。IE7~9、Chrome、FF不报错,结果为:2
}();
1
2
3
4
5
6
7
8
9
10

3、不允许修改只读属性(writeable=false)

!function () {
    var obj = { a: 1 };
    Object.defineProperty(obj, 'a', { writable: false });
    obj.a = 2;
    console.log(obj.a);  //1  //证明没有被修改
}();

!function () {
    'use strict';
    var obj = { a: 1 };
    Object.defineProperty(obj, 'a', {writable: false});
    obj.a = 2;  //TypeError
}();
1
2
3
4
5
6
7
8
9
10
11
12
13

4、不允许删除参数名,函数名;非严格模式返回false,静默失败。(静默失败:不报错也没有任何效果)

!function(a) {
    console.log(a);  //1
    console.log(delete a);  //false
    console.log(a);  //1
}(1);

!function(a) {
    'use strict';
    console.log(a);  //1
    delete a;  //SyntaxError(语法错误)
    console.log(a);  //1
}(1)
1
2
3
4
5
6
7
8
9
10
11
12

5、不允许重复参数名

!function (a, a, b) {
    console.log(a + b);  //5
}(1, 2, 3);

!function (a, a, b) {
    'use strict';
    console.log(a + b);  //SyntaxError
}(1, 2, 3);
1
2
3
4
5
6
7
8

6、未来保留关键字,不能用作变量,函数名 package, private, protected, public, static, yield,eval

7、禁止八进制字面量或参数或转义字符

8、严格模式下,一般函数调用(不是对象的方法调用,也不使用apply/call/bind等修改this),this指向undefined,而不是全局对象

!function () {
    function fun() { return this; }
    console.log( fun() );  //Window
}();

!function () {
    'use strict';
    function fun() { return this; }
    console.log( fun() );  //undefined
}();
1
2
3
4
5
6
7
8
9
10

9、严格模式下,禁止了不在脚本或者函数层面上的函数声明

!function () {
    "use strict";
    if (true) {
        function fun() {}
        console.log( fun() );  //IE10报错。IE11、IE7~9、Chrome、FF不报错。
    }

    for (var i = 0; i < 5; i++) {
        function fun2() {}
        console.log( fun2() );  //IE10报错。IE11、IE7~9、Chrome、FF不报错。
    }

    function fun3() {  // 合法
        function fun4() {}  //同样合法
    }
}();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

10、严格模式下,eval变成了独立作用域。如果在eval函数内声明变量,则不能在函数外部使用该变量

!function() {
    eval('var evalVal = 2;');
    console.log(typeof evalVal);  //number
}();

!function() {
    'use strict';
    eval('var evalVal = 2;');
    console.log(typeof evalVal);  //undefined
}();
1
2
3
4
5
6
7
8
9
10

11、严格模式下,arguments变为参数的静态副本。非严格模式下,arguments对象里的元素和对应的参数是指向同一个值的引用;

!function(a) {
    arguments[0] = 100;
    console.log(a);  //100
}(1);

!function(a) {
    'use strict';
    arguments[0] = 100;
    console.log(a);  //1
}(1);
1
2
3
4
5
6
7
8
9
10

但是:传的参数是对象除外。arguments和形参共享传递。

!function(a) {
    'use strict';
    console.log(a.x);  //1
    arguments[0].x = 100;
    console.log(a.x);  //100
}({x: 1});
1
2
3
4
5
6

12、严格模式下,不允许使用with。会延长作用域

!function () {
    with({ x: 1 }) {
        console.log(x);  //1
    }
}()

!function () {
    'use strict';
    with({ x: 1 }) {
        console.log(x);  //SyntaxError
    }
}()
1
2
3
4
5
6
7
8
9
10
11
12

13、严格模式下,不再支持arguments.callee。

!function () {
    'use strict';
    var fun = function () { return arguments.callee; };
    fun(); //TypeError
}();
1
2
3
4
5

# JSON格式

1、用 stringify 输出的结果是以严格模式来返回给我们的。 2、stringify的第二个参数也是一个函数。 不过stringify的第二个参数,主要是过滤作用。

var json = {a:20, b:30, c:50};
console.log(JSON.stringify(json, function(key, value) {
     if(value == 30) {
        return undefined;
     } else {
        return value;
     }
}));
// {"a":"20", "c":"50"};
1
2
3
4
5
6
7
8
9

上面代码的意思是,如果value是30,就返回undefined,其他的返回自身value。 所以输出的时候,b就没了。 3、stringify 还有第三个参数,作用是推进(缩进字符:最多10)。

var json = {a:20, b:30, c:50};
console.log(JSON.stringify(json, function(key, value) {
if(value == 30) {
    return undefined;
    } else {
    return value;
}
}, 1));
输出结果为:
{
    "a": 20,
    "c": 50
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 添加对象

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/object

1、Object.keys() 获取对象的key 2、Object.create() 获取对象的副本,实现类的继承 3、Object.assign() 浅拷贝 4、Object.defineProperty(onj, prop, descriptor) 直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。 5、Object.defineProperties(obj, props) 在其上定义或修改属性的对象。 6、Object.entries() 返回一个给定对象自身可枚举属性的键值对数组 7、Onject.fromEntries() 可以将 Map 转化为 Object:

const map = new Map([ ['foo', 'bar'], ['baz', 42] ]);
const obj = Object.fromEntries(map);
console.log(obj); // { foo: "bar", baz: 42 }
1
2
3

8、Object.freeze() 可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。该方法返回被冻结的对象。 9、Object.is() 判断两个值是否是相同的值 10、Object.values() 返回一个数组,其元素是在对象上找到的可枚举属性值

var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]
1
2