-
var、let、const的区
使用 var
声明的变量会被提升到作用域的顶部
提升存在的根本原因就是为了解决函数间互相调用的情况
var 存在变量提升(hoisting)
console.log(a) var a=1; // undefined
解析: 等价于: var a; console.log(a); // undefined a=1;
变量提升,提升的是声明,赋值并未提升
函数页存在提升
console.log(a) //ƒ a() {} var a = 1 function a() {} // 说明函数也存在变量提升,且优先级高于变量
var a = 10; var a console.log(a) //10 // 等价于 // var a; // var a; // a = 10; // console.log(a)
声明前调用,会报错
console.log(a) //Uncaught ReferenceError: a is not defined let a = 1; // 声明前调用,报错
总结:
- 函数提升优先于变量提升,函数提升会把整个函数挪到作用域顶部,变量提升只会把声明挪到作用域顶部
var
存在提升,我们能在声明之前使用。let
、const
因为暂时性死区的原因,不能在声明前使用var
在全局作用域下声明变量会导致变量挂载在window
上,其他两者不会let
和const
作用基本一致,但是后者声明的变量不能再次赋值
2.原始集成,类继承
组合继承
function Parent(value) { this.val = value } Parent.prototype.getValue = function () { console.log(this.val) } function Child(value) { Parent.call(this, value) } Child.prototype = new Parent() const child = new Child(1) child.getValue() // 1 console.log(child instanceof Parent) // true // 上述继承,在继承父类函数的时候调用了父类构造函数,导致子类圆形上多了不需要的父类属性,造成内存的浪费
寄生组合继承
// 优化上述集合继承 function Parent(value) { this.val = value } Parent.prototype.getValue = function () { console.log(this.val) } function Child(value) { Parent.call(this, value) } Child.prototype = Object.create(Parent.prototype, { constructor: { value: Child, enumberable: false, writable: true, configurable: true } }) const child = new Child(1) child.getValue() //1 console.log(child instanceof Parent) //true
class继承
//ES6 class继承 class Parent { constructor(value) { this.val = value } getValue() { console.log(this.val) } } // class 实现继承的核心在于使用 extends 表明继承自哪个父类 class Child extends Parent { constructor(value) { super(value) // 在子类构造函数中必须调用 super,因为这段代码可以看成 Parent.call(this, value)。 this.val = value } } let child = new Child(2) child.getValue() // 2 console.log(child instanceof Parent) // true // class的本质是函数