JS基础概念

问题1 :ES6中的class 与 ES5中function的关系
ES6 中:

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

    sayHello() {
        return 'hello, I am ' + this.name;
    }
}

var kevin = new Person('Kevin');
kevin.sayHello(); // hello, I am Kevin

对应到 ES5 中就是:

function Person(name) {
    this.name = name;
}

Person.prototype.sayHello = function () {
    return 'hello, I am ' + this.name;
};

var kevin = new Person('Kevin');
kevin.sayHello(); // hello, I am Kevin

参照:
ES6 系列之 Babel 是如何编译 Class 的
https://github.com/mqyqingfeng/Blog/issues/105

问题2 :this指针在不同情况下的表现

<html>
<script>
"use strict";
  function Car(make, model, year) {
  debugger;
  this.make = make;
  this.model = model;
  this.year = year;
}

const car1 = new Car('Eagle', 'Talon TSi', 1993);

console.log(car1.make);

const myFun = () => {
	debugger;
	console.log(this);
	return 1;
}

myFun();

function fun01(){
	debugger;
 return !this;
} 
 

fun01();

</script>

</html>

第一个case:const car1 = new Car('Eagle', 'Talon TSi', 1993);
此时的this是指向对象car1的

第二个case:myFun();
此时this指向window对象,因为这个function是箭头函数,所以this指针会被提升到window

第三个case:fun01()
如果是严格模式"use strict", this指针为undefined。 如果不是严格模式, this指针指向window对象

问题3:ES6中的set、map与weakset、weakmap区别:
WeakSet 结构与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。
首先,WeakSet 的成员只能是对象,而不能是其他类型的值。
其次,WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。

map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。
map与weakmap
首先,WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
其次,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"

参考:https://es6.ruanyifeng.com/#docs/set-map

问题4:ES6中class的继承(extends) 与 ES5中的原型继承有何不同?
ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。
子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。
正确

class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
  }

  toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
  }
}

错误

class Point { /* ... */ }

class ColorPoint extends Point {
  constructor() {
  }
}

let cp = new ColorPoint(); // ReferenceError

上面代码中,ColorPoint继承了父类Point,但是它的构造函数没有调用super方法,导致新建实例时报错。

参考:https://es6.ruanyifeng.com/#docs/class-extends

posted @ 2020-11-18 19:07  老胡Andy  阅读(83)  评论(0编辑  收藏  举报