面向对象中的原型和原型链

面向对象

对象: 无序属性得集合,其属性可以包含基本类值,对象或者函数。
对象的生成方式有两种:
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上有这个方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值