面向对象
对象: 无序属性得集合,其属性可以包含基本类值,对象或者函数。
对象的生成方式有两种:
1.字面量
var obj={};//字面量
在这里要注意,这种方式和下面一种方式的本质是相同的,其相当于var obj =new Object;
2.构造函数
var obj =new Object;
构造函数的特点:
1,书写上为了区分普通的函数首字母要大写
2,使用的是this,不需要返回
3,new的方式去执行
构造函数和对象的关系是什么?
构造函数是对象的母亲,并且构造函数的基因流传给了儿子,这个基因就被称为原型
原型
1,对象和构造函数
任何的对象的出现都是被构造出来的,构造对象的方法是构造函数。构造函数生成的对象为构造函数的实例。
构造函数生成实例化对象的方式是new关键字。内部用this指代需要生成的实例化对象,添加属性与方法。构造函数函数名通常首字母大写。
function Person(name){
this.name = name;
this.say = function(){
console.log(this.name)
}
}
let p1 = new Person("Gintama");
p1;//{name: "Gintama", say: function(){console.log(this.name)}}
p1.say();//"Gintama"
构造函数的原型 构造函数名.prototype
function Foo(a){
this.leftHand=a;
this.rightHand=a;
}
Foo.prototype={
say:function(){
console.log('哇哇哇');
},
walk:function(){
console.log(this===b1);//true
}
}
var b1=new Foo(3);
var b2=new Foo(3);
在这里,b1.say(),b2.say()都可以访问原型内中的方法并输出哇哇哇
prototype是一个对象,对象里面可以添加属性,这些属性在实例化对象的时候可以使用。
在这里就有疑问了
为什么b1可以使用walk之类的方法?
为什么b1身上有Foo.prototype的内容?
如图,b1中有Foo.prototype的内容,在b1的__proto__中,访问它的属性,在这里,__proto__指的是实例化对象的原型,他和prototype的不同之处在于,一个是实例化对象,一个是构造函数。
实例化对象:通过构造函数new出来的对象;
构造函数的原型:Foo.prototype
实例化对象的隐式原型:b1. __proto__;
b1. __proto__===Foo.prototype;//true
实例化对象的隐式原型就是构造函数的原型。
我们称b1,b2这两个实例化对象继承了其构造函数得原型的方法。那它是怎么继承的?
通过 __proto__继承
任何(实例化)对象拥有一个属性constructor,构造器。它指向当前对象的构造函数。
function Person(){}
let p = new Person();
p.constructor === Person;//true
let o1 = {};
o1.constructor === Object;//true
函数也是一个对象,也有构造函数
Person.constructor === Function;//true
Function.constructor === Function;//true
Object.constructor === Function;//true
关于构造器的举例
function Person(){
this.name=a;
}
Person.prototype={
say:function(){
console.log("我的名字是${this.name}");
}
}
Person.prototype.constructor=Person;//强行改变
var p=new Person("张三");
//在强行改变之前,p.constructor===Object而不是Person
因为JavaScript是没有类的。只有基于原型。在构造函数中通过new关键字可以生成对象,和基于类的语言非常类似,所以我们称构造函数也是一个类。
实例化对象访问构造函数得方法:instanceof
function Person(name){
this.name = name;
this.say = function(){
console.log(this.name)
}
}
let p1 = new Person("Gintama");
p1 instanceof Person;//true
Object是对象,同时也是构造函数。(可以使用new Object)
Object instanceof Object;//true
Object instanceof Function;//true
因此,任何的对象都是可以看作Object的实例。
let o1 = new Object();
let o2 = {};
原型链
每一个对象都有一个原型对象,对象以原型为模板,继承原型的方法和属性。原型也可以拥有原型,也继承方法和属性,一层一层,这个关系就叫原型链。
首先,假设来自于另外一个语言FUNCTION 构造函数:创建实例化对象的。
FUNCTION.prototype===Function.__proto__;
在js中将其强行赋值
Function.prototype===Function.__proto__;
然后Function生成了一个Object并且将Object的原型修改成了自己。
Object.__proto__===Function.prototype;//true
然后Object生成了Function的原型。
Function.prototype.__proto__===Object.prototype;//true
每一个对象O都有一个隐式原型A,指向本体O构造函数的原型,隐式原型上也有隐式原型B,指向的是A构造函数得原型…类推
当我们访问一个元素的属性或者方法的时候,他会在对象上查询属性或方法,没有的时候就去隐式原型上寻找,没有就再一层一层往上找,直到找到或者到达万物的终点: Object.prototype(由上层对象生成的Object构造函数得原型,在再往上就是null了)
这个查询顺序就是原型链,这也就是为什么每个对象都有toString方法的原因了。Object.prototype上有这个方法。