js高级-构造函数和原型

本文介绍了在ES6之前如何使用构造函数和原型对象创建实例,探讨了实例成员与静态成员的区别,以及prototype对象、_proto_属性、constructor和原型链的工作原理。同时,讲解了成员查找机制、this的指向问题,以及call方法的使用。此外,还讨论了原型对象在实现继承中的作用,并展示了继承属性和方法的代码示例。最后,提到了利用原型对象扩展内置对象的方法。
摘要由CSDN通过智能技术生成

ES6之前是没有类的概念的,都是通过构造函数来解决问题。现在绝大部分浏览器都支持ES6。 

1-创建实例对象:

创建实例对象有三种方法。

1.new Object()

var a=new Object;

2.字面量

var a={};

3.构造函数

var a=function(){

this.name='zhangsan';

this.sing=function(){alert('正在唱歌');}}

var b=new a;

通过new创建实例对象,首先看到new后会开辟一个空间,然后构造函数里面的this都会指向这个空间,里面的属性和方法都会放到这个空间里面,放完后就返回这个空间,这个空间就变成了我们定义的对象。

2-实例成员和静态成员

.1.实例成员

构造函数里通过this.来写的属性和方法都是实例成员,这些成员都可以在外部通过定义的对象.属性或方法来访问。

2.静态成员

构造函数里面没有通过this来写得属性和方法都是静态的,这些无法通过实例化的对象拿到。只能通过构造函数本身来拿到。

构造函数实例化后,会造成内存浪费,那么需要通过原型来解决。

3-prototype对象

每个构造函数都有一个属性指向这个prorotype对象,所以这个对象中的属性和方法都被构造函数所拥有。因此为了避免内存浪费,我们把那些不变的方法定义在prorotype对象里面。

总结:把属性放到构造函数里面,方法放到prorotype对象里面。

当然这边还存在一个问题,当把方法定义到原型对象里面,构造函数就没有定义这个方法,我们实例化对象后,实例完的对象可以直接调用这个方法,这里就涉及到对象的一个属性_proto_。

4-_proto_属性

对象里面都有一个_proto_属性,且这个属性的指向和构造函数里面的prorotype属性的指向是一样的,都是指向原型对象。因此可以使用构造函数里的原型方法。

5-construction

原型对象里面有一个属性construction,这个属性指回构造函数本身。如果我们给原型对象赋值,就会出现下面的这种情况,这时候手动给原型对象添加construction属性,让属性指回构造函数。

假设有一个构造函数a,原型里面有方法b和c,然后往原型赋值方法b和c,即a.prototype={

b,c};那么这个原型对象不再指向构造函数,因为赋值完的原型对象里面不再有construction属性。

6-原型链

只要是对象都有原型,同理原型对象的原型是什么呢?答案那就是Object._proto_。那么这个大写的Object的原型对象是谁创造出来的?当然是Object这个构造函数。接着分析,接着奏乐,Object的原型对象指向谁呢?Null为空即返回结果为空。

因为有了原型链,所以可以从下往上查找对象成员。

7-成员查找机制

当访问一个对象的属性和方法时,首先看看这个对象自身有没有该东西,没有就看看这个对象的原型,也就是_proto_指向的对象,如果没有的话就找原型对象的原型即obeject构造函数的原型对象。再没有就没有了,因为找下去就为空,就找不到了。

8-this指向问题

构造函数中的this和原型对象里面的方法的this都是指向调用者。

9-原型对象的应用

利用原型对象可以对内置对象如数组添加自定义方法。

Array.prototype.名字=function(){},然后就可以直接使用了。如果用对象形式添加方法则要手动指回去构造函数。

10-call()

这个方法可以调用函数,更强大的是可以改变方法的this指向。

11-继承

因为ES6之前,没有像类那些extend继承父类的属性和方法,是通过构造函数继承属性,原型对象继承方法来实现继承。

下面代码继承属性。

function Father (uname,age){
    this.uname=uname;
    this.age=ageh;
}

function Son(uname,age){
Father.call(this,uname,age)
}

下面是方法继承。

function Father(){};
Father.prototype.sing();
function Son(){};
如果Son要继承Father里面的sing则把父亲的原型对象赋值给Son的原型对象。
Son.prototype=Father.prototype;

通过赋值来继承的话,会出现改变儿子的原型指向问题,那么这两个构造函数的原型是同一个,显然没有达到预期的需求。那么怎么解决?就是把Father实例后赋值给Son的原型就可以达到效果。即下面的代码。

function Father(){};
Father.prototype.sing();
function Son(){};
Son.prototype=new Father;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值