JavaScript面对对象编程
JavaScript面对对象编程和Java、c++面对对象不同(类和实例),JavaScript中更类似于通过一个方法使得一个对象继承另外一个对象属性(把一个对象的原型指向另一个对象,但是只能指向一个对象,重新__proto__后是指向另一个对象了,指向就没用了)。
var a = {
name: 'lz',
height: 1.8,
run: function () {
alert('姓名:'+this.name );
}
};
var b = {
name: 'maomao',
height: 11
};
var c = {
run: function () {
alert('姓名:'+this.name );
}
};
b.__proto__ = a;//就像是把a赋值给b,原型链指向a
b.__proto__ = c;//就像是把c赋值给b,上一条语句失效
a.name; //lz
b.name; //maomao
a.run(); //姓名:lz
b.run(); //姓名:maomao
obj.__proto__=obj;是去改变一个对象的原型,不建议这样做,所以Object.create()方法可以传入一个原型对象,并创建一个基于该原型的新对象,但是新对象什么属性都没有。
// 原型对象:
var a = {
name: 'lz',
height: 1.8,
run: function () {
alert('姓名:'+this.name );
}
};
function createObject(name) {
// 通过Object.create()把对象a传入b中
var b = Object.create(a);
// 给对象中添加初始的值
b.name = name;
return b;
}
var c = createObject('毛毛');
c.run();
我们创建的每一个函数function都有一个prototype属性,这个属性是一个指针,指向一个对象,对象中包含由所有实例共享的属性和方法。
每个对象都有一个内部属性__proto__
,我们通常称之为原型。原型的值可以是一个对象,也可以是null
。如果它的值是一个对象,则这个对象也一定有自己的原型。这样就形成了一条线性的链,我们称之为原型链。
var a = function(){};
a.prototype.run = function(){
alert("hello!");
}
var b = new a();
b.run();
访问b.run()方法时,b中没有这个方法,所以去
__proto__中找,而它指向的是另一个对象,则在这个对象中找。
构造函数创建对象:除了{…},还可以用构造函数创建对象(用new实例化一个对象,new是默认返回this的)。
var a = {
name: 'lz',
height: 1.8,
run: function () {
alert('姓名:'+this.name );
}
};
function createObject(name) {
this.name = name;
//return this;
} //注释掉也能有相同的效果
//var c =createObject('毛毛');
var c =new createObject('毛毛');
c.name;
原型链:当从一个对象那里调取属性或方法时,如果该对象自身不存在这样的属性或方法,就会去自己关联的prototype对象那里寻找,如果prototype没有,就会去prototype关联的前辈prototype那里寻找,如果再没有则继续查找Prototype.Prototype引用的对象,依次类推,直到Prototype.….Prototype为undefined(Object的Prototype就是undefined)从而形成了所谓的“原型链”。
继承:JavaScript中实现继承是通过原型链接实现的。
通过原型链继承
function Father(){ //被继承的函数叫做超类型(父类,基类)
this.name = "Jack";
}
function Son(){ //继承的函数叫做子类型(子类,派生类)
this.age = 12;
}
//通过原型链继承,赋值给子类型的原型属性
//new Father()会将father构造里的信息和原型里的信息都交给Son
Son.prototype = new Father();//Son继承了Father,通过原型,形成链条
var son = new Son();
alert(son.name);
通过class继承
/*
function Father(name) {
this.name = name;
}
Father.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
}
*///改成如下的
class Father {
constructor(name) {
this.name = name;
}
hello() {
alert('Hello, ' + this.name + '!');
}
}
var son = new Father('小明');
son.hello();
class和class之间继承(这段自己找的一直报错,很久没解决,不清楚什么问题)
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '('+this.x+', '+this.y+')';
}
}
/*
var point = new Point(2, 3);
point.toString() // (2, 3)
point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.__proto__.hasOwnProperty('toString') // true
*/
class ColorPoint extends Point {
constructor(x, y, color) {
super(x, y); // 调用父类的constructor(x, y)
this.color = color;
}
toString() {
return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}
var a = new ColorPoint(2,2,'hehe');
a.toString();