es6中的class与继承
原型链:
每个构造函数都有一个prototype属性叫做显示原型
每个实例中都有一个__proto__属性叫做隐式原型
实例的隐式原型指向它的构造函数的显示原型
每个prototype原型都有一个constructor属性,指向它关联的构造函数。
获取对象属性时,如果对象本身没有这个属性,那就会去他的原型__proto__
上去找,如果还查不到,就去找原型的原型,一直找到最顶层(Object.prototype
)为止。Object.prototype对象也有__proto__属性值为null。
用constructor检测数据类型,可以检测所有的数据类型包含构造函数,够赞韩式的contructor可以被修改,修改过后检测就会不准确
前言:
传统的javascript中只有对象,没有类的概念。它是基于原型的面向对象语言。原型对象特点就是将自身的属性共享给新对象。这样的写法相对于其它传统面向对象语言来讲,独树一帜也可以说难以接受!
ES5中的类
ES5中如果要生成一个对象实例,需要先定义一个构造函数
,然后通过new
操作符来完成。
构造函数生成实例的执行过程:
1.当使用了构造函数,并且new 构造函数(),后台会隐式执行new Object()创建对象;
2.将构造函数的作用域给新对象,(即new Object()创建出的对象),而函数体内的this就代表new Object()出来的对象。
3.执行构造函数的代码。
4.返回新对象(后台直接返回);
ES6中的类
ES6引入了
class
(类)这个概念,通过class关键字可以定义类。该关键字的出现使得javascript在对象写法上更加清晰,更像是一种面向对象的语言。注意项:
1.在类中声明方法的时候,千万不要给该方法加上function关键字 2.方法之间不要用逗号分隔,否则会报错 3.在ES6的类中依然存在着。console.log(Person.prototype);//输出的结果是一个对象,实际上类的所有方法都定义在类的prototype属性上 4.当然也可以通过prototype属性对类添加方法 5.还可以通过Object.assign方法来为对象动态增加方法 6.constructor方法是类的构造函数的默认方法,通过new命令生成对象实例时,自动调用该方法。 7.constructor方法如果没有显式定义,会隐式生成一个constructor方法。所以即使你没有添加构造函数,构造函数也是存在的。constructor方法默认返回实例对象this,但是也可以指定constructor方法返回一个全新的对象,让返回的实例对象不是该类的实例。 8.constructor中定义的属性可以称为实例属性(即定义在this对象上),constructor外声明的属性都是定义在原型上的,可以称为原型属性(即定义在class上)。hasOwnProperty()函数用于判断属性是否是实例属性。其结果是一个布尔值, true说明是实例属性,false说明不是实例属性。in操作符会在通过对象能够访问给定属性时返回true,无论该属性存在于实例中还是原型中。 9.类的所有实例共享一个原型对象,它们的原型都是Person.prototype,所以proto属性是相等的 10.由此,也可以通过proto来为类增加方法。使用实例的proto属性改写原型,会改变Class的原始定义,影响到所有实例,所以不推荐使用! 11.class不存在变量提升,所以需要先定义再使用。因为ES6不会把类的声明提升到代码头部,但是ES5就不一样,ES5存在变量提升,可以先使用,然后再定义。
ES5中的继承 (组合继承:原型链继承 + 借用构造函数)
原型链继承:
父类的实例作为子类的原型
借用构造函数继承:
在子类内,使用call()调用父类方法,并将父类的this修改为子类的this.相当于是把父类的实例属性复制了一份放到子类的函数内.
组合继承:
既能调用父类实例属性,又能调用父类原型属性
/解决方法,组合是继承,把子类的原型变成父类的实例
ES6中的 class继承
- 父类(基类)
- 子类
extends
关键字- class 相当于es5中构造函数* //class中定义方法时,前后不能加function,全部定义在class的protopyte属性中 //class中定义的所有方法是不可枚举的 //class中只能定义方法,不能定义对象,变量等 //class和方法内默认都是严格模式 //es5中constructor为隐式属性
promise
一般来讲,有以下的名词约定:
promise
(首字母小写)对象指的是“Promise实例对象”Promise
首字母大写且单数形式,表示“Promise构造函数”Promises
首字母大写且复数形式,用于指代“Promises规范”
什么是Promise?
-
Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
从语法上说,promise 是一个对象,从它可以获取异步操作的的最终状态(成功或失败)。
Promise是一个构造函数,对外提供统一的 API,自己身上有all、reject、resolve等方法,原型上有then、catch等方法。 -
Promise的两个特点
-
Promise对象的状态不受外界影响
1)pending 初始状态
2)fulfilled 成功状态
3)rejected 失败状态
Promise 有以上三种状态,只有异步操作的结果可以决定当前是哪一种状态,其他任何操作都无法改变这个状态 -
Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,只能由 pending变成fulfilled或者由pending变成rejected
有哪些状态和参数?如何使用?
- 主要用于异步计算
- 可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
- 可以在对象之间传递和操作 promise,帮助我们处理队列
resolve 作用是,将 Promise 对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject 作用是,将 Promise 对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
promise 有三个状态:
-
pending[待定]初始状态
-
fulfilled[实现]操作成功
-
rejected[被否决]操作失败
-
当 promise 状态发生改变,就会触发 then()里的响应函数处理后续步骤
-
一、什么是闭包:
①要理解闭包,首先理解javascript特殊的变量作用域,变量的作用于无非就是两种:全局变量,局部变量。
②javascript语言的特殊处就是函数内部可以读取外部作用域中的变量。
③我们有时候需要得到函数内的局部变量,但是在正常情况下,这是不能读取到的,这时候就需要用到闭包。在javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。闭包是指有权访问另一个函数作用域中的变量的函数。其本质是函数的作用域链中保存着外部函数变量对象的引用。
二.闭包的应用场景:
①函数作为参数被传递
②函数作为返回值被返回
③实际应用(隐藏数据):为什么说隐藏数据了呢,因为普通用户只能通过get、set等api对数据进行查看和更改等操作,没法对data直接更改,达到所谓隐藏数据的效果;jquery就利用了这一特性,必须调用$.ajax()才能访问内部属性方法。
封装功能时(需要使用私有的属性和方法),
函数防抖、函数节流
单例模式
三.闭包的优点:
(一)变量长期驻扎在内存中
(二)另一个就是可以重复使用变量,并且不会造成变量污染
①全局变量可以重复使用,但是容易造成变量污染。不同的地方定义了相同的全局变量,这样就会产生混乱。”
②局部变量仅在局部作用域内有效,不可以重复使用,不会造成变量污染。
③闭包结合了全局变量和局部变量的优点。可以重复使用变量,并且不会造成变量污染
四.闭包的缺点:
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
this总结 (重要)
普通函数中调用,this指向window
对象方法中调用,this指向当前对象
call apply bind中调用, this指向被传入的对象
class中的方法中调用, this指向实例对象
箭头函数,this就是父级