<
JavaScript 笔记
>
上一篇

随笔
下一篇

了解 Web 前端的工作内容
苏轻最后编辑于 2019 年 03 月 04 日 17:06:25

目录 | | 闭包 | JSON |

资料 | MDN Web Docs - JavaScript |

  使用 class 关键字声明一个类。

class Person {
    constructor(name, age, height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }
}

  使用一个类表达式来定义一个类。

/// 一个匿名的类
let Person = class {
    constructor() {
        // ...
    }
};
// 一个命名的类
let Animal = class Animal {
    constructor() {
        // ...
    }
};

  构造函数 constructor 方法用于创建和初始化一个由 class 创建的对象,一个类有且只能有一个 constructor 方法。

  一个构造函数可以使用 super 关键字来调用一个父类的构造函数。

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    static distance(a, b) {
        const dx = a.x - b.x;
        const dy = a.y - b.y;
        return Math.hypot(dx, dy); // 所有参数的平方和的平方根
    }
}

const p1 = new Point(3, 4);
const p2 = new Point(12, 13);
Point.distance(p1, p2); // p1 p2 两点之间的距离

  static 关键字用来定义一个类的一个静态方法。调用静态方法不需要实例化该类,静态方法通常用于创建工具函数。

class Animal {
    constructor(name) {
        this.name = name;
    }
    speak() {
        alert(this.name + " makes noise.");
    }
}
class Dog extends Animal {
    speak() {
        alert(this.name + " barks.");
    }
}
var dog = new Dog("Hei");
dog.speak();

  extends 关键字在类声明或类表达式中用于创建一个类作为另一个类的一个子类。

class Person {
    constructor(name) {
        this.name = name;
    }
}
class Student extends Person {
    constructor(name, level) {
        super();
        this.name = name;
        this.level = level;
    }
}

  如果子类中存在构造函数,则需要在使用 this 之前首先调用 super()

闭包

  先来看一段代码。

function output() {
    var name = "sq";
    function showName() {
        alert(name);
    }
    showName();
}

  在 JavaScript 中,嵌套的函数可以访问在其外部声明的变量,并且,JavaScript 中的函数会形成闭包。

  再来看一段代码。

function showName() {
    var name = "sq";
    return function() {
        alert(name);
    }
}
var output = showName();
output();

  闭包是由函数以及创建该函数的词法环境组合而成,这个环境包含了这个闭包创建时所能访问的所有局部变量

  所以,showName() 返回的匿名函数,永远可以访问它的词法作用域中的变量,即可以访问到 name

  下面再来一段更加有意思的。

function makeSizer(size) {
    return function() {
        document.body.style.fontSize = size + 'px';
    };
}
var size12 = makeSizer(12); // =function(){fontSize = "12px"}
var size32 = makeSizer(32);
size32();

  size12size32 都是闭包。它们共享相同的函数定义,但是保存了不同的词法环境。而这里的 makeSizer() 则更像一个函数的制造工厂,可以制造设定 fontSize 的函数,这就是闭包的实用价值。

  然而还远不止于此,再看。

var Counter = (function() {
    var count = 0;
    return {
        inc : function() {
            count += 1;
        },
        dec : function() {
            count -= 1;
        },
        value : function() {
            return count;
        }
    };
})();

Counter.value(); // 0
Counter.inc();
Counter.inc();
Counter.value(); // 2
Counter.dec();
Counter.value(); // 1

  Counter 对象内部的 count 变量只能通过三个公共函数访问,相同的词法环境被这三个函数所共享。

  私有方法不仅仅有利于限制对代码的访问,还提供了管理全局命名空间的强大能力,避免非核心的方法弄乱了代码的公共接口部分。虽然 JavaScript 没有这种原生支持,但我们可以使用闭包来模拟私有方法。

  以这种方式使用闭包,提供了许多与面向对象编程相关的好处,特别是数据隐藏和封装。但如果不是某些特定任务需要使用闭包,在函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响,这点一定要记住。

JSON

  JSON 的全称为 JavaScript Object Notation,意为 JS 对象表示法。JSON 和 JavaScript 的对象格式一致,但是属性名都加了双引号。

var obj = '{"name":"sq","age":"18"}';   // JSON 格式的对象
var arr = '[1,2,3,true,"hello world"]'; // JSON 格式的数组

  JSON 格式的字符串可以被任意的语言识别,然后转换为任意语言的对象。不同的语言之间在进行数据交互时,通常使用 JSON。

// JSON 对象的两个方法
var json = '{"name":"sq","age":"18"}';
var object = JSON.parse(json); // JSON 字符串 -> JS 对象
var json2 = JSON.stringify(object); // JS 对象 -> JSON 字符串

  JSON 这个对象在 IE7 及以下的浏览器中不支持,如果一定要求兼容的话可以引入外部的 JavaScript 文件。

END

Top
Foot