首页 > 技术文章 > 生成器、递归、对象拷贝

huangtonghui 2018-03-27 20:57 原文

  //生成器( generator)是能返回一个迭代器的函数
    function *createIterator() {
        yield 1;
        yield 2;
        yield time();
        yield time();
    }

    function time() {
        return new Date();
    }

    // 生成器能像正规函数那样被调用,但会返回一个迭代器
    var iterator = createIterator();

    // 返回的对象具有两个属性:done和value。
    // value是你获得的值,done用来表明你的generator是否已经停止提供值
    console.log(iterator.next()); // 1
    console.log(iterator.next()); // 2

    setTimeout(() => {
        console.log(iterator.next());
    },1000);
    setTimeout(() => {
        console.log(iterator.next());
    },2000);
    setTimeout(() => {
        console.log(iterator.next());
    },3000);

  

    /*
      函数调用自身,称为递归。如果尾调用自身,就称为尾递归。
      递归非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)。
      但对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出”错误。
    */
    
    // 递归
    function factorial(n) {
        if (n === 1) return 1;
        return n * factorial(n - 1);
    }
    factorial(5) // 120
    
    // 尾递归
    function factorial(n, total) {
        if (n === 1) return total;
        return factorial(n - 1, n * total);
    }
    factorial(5, 1) // 120

  

// 浅拷贝(合并到target)
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
 
// 浅拷贝(合并到target,有重复的会被后面覆盖,有同名属性慎用!)
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
 
// 深拷贝(合并包含继承的不可枚举属性和Symbol)
const obj = {
    __proto__: {'a':1},
    foo: 123,
};
 
 // 写法2
const obj2 = Object.create({'a':2});
obj2.foo = 123;
 
// 写法3
const obj3 = Object.assign(
    Object.create({'a':3}),
    {
        foo: 123,
    }
);
 
// 写法4
const obj4 = Object.create(
    {'a':4},
    Object.getOwnPropertyDescriptors({
        foo: 123,
    })
)

  

推荐阅读