面向对象
面向对象是高级语言的特性,对象具有封装性,继承性,多态性;
创建对象
创建一个Object实例
- var obj = {}; //字面量
- var obj = new Object(); //构造函数
批量创建对象
工厂模式
function person(n,a,g){
var o = {};
o.name = n;
o.age = a;
o.gender = g;
o.say = function(word){console.log(word)};
return o;
}
- 对创建对象的重复代码进行封装,使其复用;
- 创建输出的对象都是独立的Object个体,互不关联;
构造函数+原型
function Person(n,a,g){
this.name = n;
this.age = a;
this.gender = g;
};
Person.prototype.cate = '人';
Person.prototype.say = function(word){console.log(word)};
let page = new Person('page','20','男');
- 构造函数自动创建Object实例,函数内this指向该实例,执行内部代码并返回实例
- 构造函数内,实例的_proto_设置为自身的prototype,设置实例的原型
-
为实例原型,即Person.prototype添加属性和方法,由于原型链,所有Person实例都能共享同一个prototype的方法和属性
-
手写new操作符
function newObject(classFunc,...options){ let newObj = {}; // 将newObj._proto_指向函数的prototype Object.setPrototypeOf(newObj,classFunc.prototype); let result = classFunc.apply(newObj,options); return result instanceof Object ? result : newObj; }
-
注:什么是原型链
js通过原型链实现继承,即每个对象实例都有一个_proto_的属性,该属性指向一个作为当前实例原型的对象。当访问实例的某个属性时,js会自动在实例上搜索,没找到则在该实例的原型上搜索,实例原型不存在则在原型对象的_proto_指向的对象上继续搜索,搜索中多个_proto_之间形成的关联即原型链
继承
原型链上每个类的实例继承构造函数的prototype,如果我们希望protype继承另一个对象,这样实例就能拥有该对象的属性/方法
prototype原型
Subtype.prototype = new Suptype();
Suntype.prototype.ownMethod = function(){...}; //自己的方法
让类的原型指向超类的实例,实现继承;
为什么不直接这样写?
Subtype.prototype = Suptype().prototype;
Subtype.prototype.ownMethod = function(){...}; //自己的方法
- 这会使Subtype.prototype和Suptype.prototype指向同一个对象
- 意味着Subtype.proyotype.constructor值为Suptype,这不是我们想要的,这不符合继承;
- 为了控制Subtype实例,我们对Subtype.prototype的操作也会影响到Suptype的实例,这是因为二者是平级关系,而非继承
Object.create()
let o = {cate: '人',say(){console.log(this.cate)}};
创建一个继承o的对象,使其拥有o的全部属性/方法(单例对象的继承)
// 设置原型即可
var obj = {};
Object.setPrototypeOf(obj,o);
// or
function createBy(obj){ // 创建临时构造函数,
let Fn = function(){}; // 利用构造函数的new设置返回实例的原型为o
Fn.prototype = obj;
return new Fn();
};
let obj = createBy(o);
-
构造函数
想让Subtype继承Suptype构造函数内的属性,我们可以
Subtype.prototype = new Suptype('男'); // 实例化一个Suptype实例作为原型
这确实能让Subtype实例拥有确定的Suptype属性,但所有Subtype实例的Suptype属性都是一个固定值,如果你想个性化化每个Subtype的属性值,尝试
Subtype(gender){
Suptype.call(this,'gender);
};
Subtype.prototype = new Suptype();