JavaScript_02_notes

4. 迭代

迭代是按照顺序反复多次执行一段程序,通常会有明确的终止条件。ECMAScript 6 规范新增了两个高级特性:迭代器生成器。使用这两个特性,能够更清晰、高效、方便地实现迭代。

迭代器指任何实现Iterator接口的对象。每个迭代器都会关联一个可迭代对象,而迭代器会暴露该对象的 API。迭代器无须了解该对象的结构,只需要知道如何取得连续的值。

//实现了 Iterator 接口,但它的每个实例只能被迭代一次
class Counter {
    // Counter 的实例应该迭代 limit 次
    constructor(limit) {
        this.count = 1;
        this.limit = limit;
    }
    //
    next() {
        if (this.count <= this.limit) {
            return { done: false, value: this.count++ };
        } else {
            return { done: true, value: undefined };
        }
    }
    //
    [Symbol.iterator]() {
        return this;
    }
}

//创建多个迭代器:把计数器变量放到闭包里,然后通过闭包返回迭代器
class Counter {
    //
    constructor(limit) {
        this.limit = limit;
    }
    //
    [Symbol.iterator]() {
        let count = 1,
        limit = this.limit;
        return {
            next() {
                if (count <= limit) {
                    return { done: false, value: count++ };
                } else {
                    return { done: true, value: undefined };
                }
            }
        };
    }
}

let counter = new Counter(3);
for (let i of counter) {
    console.log(i);
}

// return方法,用于指定在迭代器提前关闭时执行的逻辑。可选,略。

生成器结构拥有在一个函数块内暂停和恢复代码执行的能力。其形式是一个函数,在函数名称前面加一个星号( *)表示。
调用生成器函数会产生一个生成器对象,它一开始处于暂停执行(suspended)的状态。调用next()方法会让生成器开始或恢复执行。yield关键字可以让生成器停止和开始执行。生成器函数在遇到yield前会正常执行。遇到后,执行则会停止,函数作用域的状态会被保留。停止执行的生成器函数只能通过在生成器对象上调用next()方法来恢复执行。
因为生成器对象实现了 Iterable 接口,而且生成器函数和默认迭代器被调用之后都产生迭代器,
所以生成器格外适合作为默认迭代器。

// 例1:
function* generatorFn() {
    yield 1;
    yield 2;
    yield 3;
}

function* generatorFn() {
    yield* [1, 2, 3];
}

//相较显式调用next()方法,把生成器对象当成可迭代对象使用起来更方便
for (const x of generatorFn()) {
    console.log(x);
}

// 例2:使用`yield*`实现递归操作。
function* nTimes(n) {
    if (n > 0) {
        yield* nTimes(n - 1);
        yield n - 1;
    }
}

5. 对象、类

ECMA-262 将对象定义为一组属性的无序集合。对象的每个属性或方法都由一个名称来标识,这个名称映射到一个值(数据或函数)。

//创建自定义对象:创建 Object 的一个新实例,然后再给它添加属性和方法
let person = new Object();
person.name = "Nicholas";
person.age = 29;
person.sayName = function() {
    console.log(this.name);
    };

//创建自定义对象:字面量
let person = {
    name: "Nicholas",
    age: 29,
    sayName() {
        console.log(this.name);
    }
};

以上两种方法创建具有同样接口的多个对象需要重复编写很多代码。

//工厂模式
function createPerson(name, age) {
    let o = new Object();
    o.name = name;
    o.age = age;
    o.sayName = function() {
        console.log(this.name);
    };
    return o;
}
let person1 = createPerson("Nicholas", 29);

//自定义构造函数,可以确保实例被标识为特定类型
function Person(name, age){
    this.name = name;
    this.age = age;
    this.sayName = function() {
        console.log(this.name);
    };
} 
let person1 = new Person("Nicholas", 29);

//原型模式

属性分两种。①数据属性包含一个保存数据值的位置。值会从这个位置读取或写入。数据属性有 4个内部特性: [[Configurable]], [[Enumerable]], [[Writable]], [[Value]]。②访问器属性包含一个获取getter函数和一个设置setter函数,但都不是必需的。访问器属性有4个内部特性:[[Configurable]], [[Enumerable]], [[Get]], [[Set]]。

属性定义方法: Object.defineProperty(), Object.defineProperties(),
属性读取方法: Object.getOwnPropertyDescriptor(),
对象合并方法: Object.assign(),
相等判定方法: Object.is(),
语法糖:简写属性名,可计算属性,简写方法名,

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值