JavaScript基础-面向对象设计
这边主要的是ES5及之前版本的js面向对象设计。由于工作的原因,我这边上手就是ES6,正因为这样在看面试题的时候才发现原来对于之前的js封装这一块的缺失。不管怎么说,缺什么,补什么,记不牢,先笔记。
首先需要注意的是,之后的js或者JavaScript都特指ES5及之前版本。
其实js算不上严格的面向对象(Object-Oriented,OO)语言,因为它有对象但并没有严格意义上的class,同样的没有class也就谈不上extends,所以下面的其实更应该说是”伪类”,”伪继承”。下面具体看看这方面的梳理吧。
创建对象
对于js而言{}就是一个对象,当然new Object()也是一个对象。《JavaScript高级编程》中提到了多种创建对象的模式,个人习惯使用其中3种——构造函数模型,原型模式,混合模型
从下文也可以看出来,js中将这些【创建对象的模式】当成了class,不过就实际情况来说,【混合模式】已经很像java中的class了
构造函数模型
定义方式:
1
2
3
4
5function Person (name,..){
this.name = name;
..
this.call = function (){};
}注意点:
- 本质上是个函数。
- 使用new创建对象,函数名首字母大写,直接将属性赋给this,没有return。
- 缺点:每个实例都将重新创建所有的属性。
原型模型
prototype中的属性,定义方式:
1
2
3function Person (){}
Person.prototype.name = "name";
Person.prototype.call = function (){};注意点:
1.【原型模型】其实是包含【构造函数模型】;- 而且prototype的属性对立于对象实例,也就是不能通过实例改变的值。
- 调用对象属性时,会先查看是否有【实例属性】,没有时再查看【原型属性】。
- 当通过实例”改变”某个【模型属性】时,实际上是创建了一个同名【实例属性】覆盖了。但在改变对象属性中的属性时,就会因为共享而导致错误。
混合模型(构造函数模型-原型模式)
由于【构造函数模型】-【原型模式】优缺互补,一般实际使用都是【混合模式】——使用【构造函数模型】创建实例私有属性,使用【原型模式】创建共享属性
other
- 使用实例的
hasOwnProperty(key:string)判断属性是否是实例属性。 [key:string] in objectobject实例是否包含属性key。for-in遍历对象属性。
- 使用实例的
继承
如同上面所说的,js没有严格意义上的继承。
普通继承
与其说是继承,还不如说是合并两个对象生产新对象。而且继承是class的事,因为是”伪”的,所以这就当是吧。
1
var p = Object.create({..},{..});
构建函数继承
具体的原理其实就是用call调用被继承函数,因为传入的this指向当前函数,也就是说所有的属性都绑定在了当前构造函数上。但这样也就只能继承【实例属性】
1
2
3
4function Son (..){
Person.call(this,..);
...
}原型继承
只能继承【原型属性】
1
2Son.prototype = Object.create(Person.protptype); //或者 Son.prototype = new Person();
...组合继承
组合【构建函数继承】和【原型继承】,如此技能继承【实例属性】,又能使用【原型属性】。