美文网首页
陌生知识点汇总(持续更新)

陌生知识点汇总(持续更新)

作者: 悄敲 | 来源:发表于2019-03-07 21:55 被阅读0次
    1. ['1', '2', '3'].map(parseInt)的结果是什么?
      Answer

    2. 函数参数对象arguments与ES6新增的rest参数都是数组吗?
      Answer:arguments对象不是数组,而是一个类似数组的对象。所以为了使用数组的方法,需先使用Array.prototype.slice.call先将其转为数组。rest 参数就不存在这个问题,它就是一个真正的数组,数组特有的方法都可以使用。

    3. 箭头函数有几个使用注意点。
      详细资料
      (1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。(
      箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值。这就意味着如果箭头函数被非箭头函数包含,this 绑定的就是最近一层非箭头函数的 this。因为箭头函数没有 this,所以也不能用 call()、apply()、bind() 这些方法改变 this 的指向).

    // ES6
    function foo() {
      setTimeout(() => {
        console.log('id:', this.id);
      }, 100);
    }
    
    // ES5
    function foo() {
      var _this = this;
    
      setTimeout(function () {
        console.log('id:', _this.id);
      }, 100);
    }
    

    (2)不可以当作构造函数,即不可以使用new命令,否则会抛出一个错误。也就没有new.target原型super
    (3)没有自己的 arguments 对象,可以用 rest 参数代替。但箭头函数可以访问外围函数的 arguments 对象。
    (4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

    1. super: 指向当前对象的原型对象。super关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错。(目前,只有对象方法的简写法可以让 JavaScript 引擎确认,定义的是对象的方法。)
    // 报错
    const obj = {
      foo: super.foo
    }
    
    // 报错
    const obj = {
      foo: () => super.foo
    }
    
    // 报错
    const obj = {
      foo: function () {
        return super.foo
      }
    }
    
    // 正常
    const proto = {
      foo: 'hello'
    };
    const obj = {
      foo: 'world',
      find() {
        return super.foo;
      }
    };
    Object.setPrototypeOf(obj, proto);
    obj.find() // "hello"
    
    1. Object.assign: 将源对象(source)的所有可枚举属性(不包括继承属性),复制到目标对象(target)。
      特点:
      (1)属于浅拷贝:如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
      (2)同名属性的替换。
    const target = { a: { b: 'c', d: 'e' } }
    const source = { a: { b: 'hello' } }
    Object.assign(target, source)
    // { a: { b: 'hello' } }
    

    (3)对数组的处理:将数组视为对象。

    Object.assign([1, 2, 3], [4, 5])
    // [4, 5, 3]
    

    Object.assign把数组视为属性名为 0、1、2 的对象,因此源数组的 0 号属性4覆盖了目标数组的 0 号属性1。
    (4) 取值函数的处理: Object.assign只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。

    const source = {
      get foo() { return 1 }
    };
    const target = {};
    
    Object.assign(target, source)
    // { foo: 1 }
    

    上面代码中,source对象的foo属性是一个取值函数,Object.assign不会复制这个取值函数,只会拿到值以后,将这个值复制过去。
    用途:
    (1)为对象添加属性;
    (2)为对象添加方法;
    (3)克隆对象:将原始对象拷贝到一个空对象,就得到了原始对象的克隆。不过这样不会克隆原始对象继承的属性。如果想要保持继承链,可以采用下面的代码。

    function clone(origin) {
      let originProto = Object.getPrototypeOf(origin);
      return Object.assign(Object.create(originProto), origin);
    }
    

    (4)合并多个对象;
    (5)为属性指定默认值。

    1. Symbol:ES6新引入的一种原始数据类型,表示独一无二的值。
      详细资料
    let s=Symbol();
    typeof s; // symbol
    

    Symbol函数前不能使用new命令,这是因为生成的 Symbol 是一个原始类型的值,不是对象。由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。

    1. js扩展运算符...:ES6新增,内部使用for...of循环,可将一个数组(或数组类似结构)转为用逗号分隔的序列。可用于:
      (1)复制数组(对原数组无影响)
    var a = ['1','2','3']
        var b = [...a]
        console.log(b) // ['1','2','3']  
    

    (2)拼接数组

     var a = [1,2,3]
       var a = [4,5,6]
       a  = [...a, ...b]
       console.log(a) // [1,2,3,4,5,6]
    

    (3)便于使用Math方法获取数组最大最小值

    var a = [1,2,3,4,5]
          var max = Math.max(...a)
          console.log(max) // 5
    

    (4)字符串转换为字符数组

    var a = 'helloworld'
          var b = [...a]
          console.log(b) // ['h','e','l','l','o','w','o','r','l','d']
    

    8-1. Set:字面意思就是集合,ES6新增的数据结构,类似于数组,但其中的元素不重复。
    (1)可利用Set去除数组的重复元素:

    [...new Set(array)]
    // or
    Array.from(new Set(array));
    

    (2)可利用Set去除字符串中的重复字符:

    [...new Set('abbccd')].join(''); // 'abcd'
    

    (3)求集合的并集、交集、差集

    let a = new Set([1, 2, 3]);
    let b = new Set([4, 3, 2]);
    
    // 并集
    let union = new Set([...a, ...b]);
    // Set {1, 2, 3, 4}
    
    // 交集
    let intersect = new Set([...a].filter(x => b.has(x)));
    // set {2, 3}
    
    // 差集
    let difference = new Set([...a].filter(x => !b.has(x)));
    // Set {1}
    

    8-2: WeakSet, Map, WeakMap:详细介绍

    WeakSetWeakMap 相比较对于的SetMap,不同点:(1)成员(for Set)或键名(for Map)都只能是对象;
    (2)成员或键名所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内。因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,(WeakSet)WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用,WeakMap的专用场合就是,它的键所对应的对象,可能会在将来消失。WeakMap结构有助于防止内存泄漏。.
    一个典型应用场景是,在网页的 DOM 元素上添加数据(例如说明性的信息),就可以使用WeakMap结构。当该 DOM 元素被清除,其所对应的WeakMap记录就会自动被移除。

    const wm = new WeakMap();
    const element = document.getElementById('example');
    
    wm.set(element, 'some information');
    wm.get(element) // "some information"
    

    上面的 DOM 节点对象 element 的引用计数是1,而不是2。这时,一旦消除对该节点的引用,它占用的内存就会被垃圾回收机制释放。Weakmap 保存的这个键值对,也会自动消失。
    注意,WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用。

    const wm = new WeakMap();
    let key = {};
    let obj = {foo: 1};
    
    wm.set(key, obj);
    obj = null;
    wm.get(key); // Object {foo: 1}
    

    上面代码中,键值obj是正常引用。所以,即使在 WeakMap 外部消除了obj的引用,WeakMap 内部的引用依然存在。

    1. Proxy:可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
      Proxy 对象可以拦截目标对象的任意属性,这使得它很合适用来写 Web 服务的客户端
      this问题:虽然 Proxy 可以代理针对目标对象的访问,但它不是目标对象的透明代理,即不做任何拦截的情况下,也无法保证与目标对象的行为一致。主要原因就是在 Proxy 代理的情况下,目标对象内部的this关键字会指向 Proxy 代理
    const target = {
      m: function () {
        console.log(this === proxy);
      }
    };
    const handler = {};
    
    const proxy = new Proxy(target, handler);
    
    target.m() // false
    proxy.m()  // true
    

    10.Reflect:详细介绍
    Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。
    (1) 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。)
    (2) 修改某些Object方法的返回结果,让其变得更合理。
    (3) 让Object操作都变成函数行为。某些Object操作是命令式,比如name in obj和delete obj[name],而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为。
    (4)Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。

    Note:Reflect.apply方法等同于Function.prototype.apply.call(func, thisArg, args),用于绑定this对象后执行给定函数。
    一般来说,如果要绑定一个函数的this对象,可以这样写fn.apply(obj, args),但是如果函数定义了自己的 apply 方法,就只能写成Function.prototype.apply.call(fn, obj, args),采用Reflect对象可以简化这种操作。

    利用 Proxy 和 Reflect 实现观察者模式
    观察者模式(Observer mode)指的是函数自动观察数据对象,一旦对象有变化,函数就会自动执行。
    下面,使用 Proxy 写一个观察者模式的最简单实现,即实现observable和observe这两个函数。思路是observable函数返回一个原始对象的 Proxy 代理,拦截赋值操作,触发充当观察者的各个函数。

    const queuedObservers = new Set();
    
    const observe = fn => queuedObservers.add(fn);
    const observable = obj => new Proxy(obj, {set});
    
    function set(target, key, value, receiver) {
      const result = Reflect.set(target, key, value, receiver);
      queuedObservers.forEach(observer => observer());
      return result;
    }
    

    上面代码中,先定义了一个Set集合,所有观察者函数都放进这个集合。然后,observable函数返回原始对象的代理,拦截赋值操作。拦截函数set之中,会自动执行所有观察者。

    11.Promise:详细资料
    简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,通过它可以获取异步操作的消息。(Promise一旦新建后就会立即执行)。
    特点:
    (1)Promise对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态。
    (2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。

    有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

    缺点
    (1)无法取消Promise,一旦新建它就会立即执行,无法中途取消。
    (2)如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
    (3)当处于pending状态时,无法得知具体进度信息(刚刚开始还是即将完成)。

    let promise = new Promise(function(resolve, reject) {
      console.log('Promise');
      resolve();
    });
    
    promise.then(function() {
      console.log('resolved.');
    });
    
    console.log('Hi!');
    
    // Promise
    // Hi!
    // resolved
    

    上面代码中,Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。
    then: then方法定义在原型对象Promise.prototype上,它的作用是为 Promise 实例添加状态改变时的回调函数。
    then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。
    catch:是 then(null, rejection) 或 then(undefined, rejection) 的别名,用于指定发生错误时的回调函数。
    (1)Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被catch语句捕获为止。(在有 catch 的前提下,如果没有catch,错误不会被捕获,也不会传递到外层。因为Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。)
    (2)一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。
    (3)catch方法返回的还是一个 Promise 对象,因此后面还可以接着调用then方法。(而且catch方法之中,还能再抛出错误。)

    1. 排序算法稳定性:不稳定:快选堆希
      稳 定:插冒归基

    13.iterator:详细介绍
    它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
    作用:
    (1)为各种数据结构,提供一个统一的、简便的访问接口;
    (2)使得数据结构的成员能够按某种次序排列;
    (3) ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。
    Iterator 的遍历过程是这样的。
    (1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
    (2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
    (3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
    (4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。
    原生具备 Iterator 接口的数据结构如下
    Array Map Set String TypedArray 函数的 arguments 对象
    NodeList 对象
    (除了Array、Map、Set,其他的都属于类数组结构(所谓类数组,就是存在数值键名和 length属性))。

    只要某个数据结构部署了 Iterator 接口,就可以对它使用扩展运算符,将其转为数组。

    1. http常见简单例子:
      (1)输入URL打开网页;
      (2)AJAX获取数据;
      (3)img标签加载图片;

    2. 数组的reduce方法:缩小方法,接收两个参数,一个在每一个数组元素上调用的函数,一个(可选的)作为缩小基础的初始值。第一个参数是一个函数,它有4个参数:前一个值(prev),当前值(cur),当前项的索引,数组对象。这个函数的返回值会作为下一项的 prev。
      如果指定了 reduce 方法中作为缩小基础的第二个参数(init),即初始值,那么第一次迭代发生在数组第一项上,即 prev=init, cur=arr[0].
      否则,第一次迭代发生在数组第二项上,即 prev=arr[0], cur=arr[1].

    相关文章

      网友评论

          本文标题:陌生知识点汇总(持续更新)

          本文链接:https://www.haomeiwen.com/subject/shzhpqtx.html