浅谈js的面向对象

js没有类

最开始的时候,我以为所有面相对象的语言都会有类的概念。然而js告诉了我,我还是太native。
JavaScript从发明的那天起就没有真正的类,虽然有不少JavaScript书籍或文章中都讲到了类,就好像JavaScript中真的存在类一样.但其实,他们所说的类只是一些自定义的构造函数,这些函数可以用来构造一些自定义的引用类型.在JavaScript中,引用类型已经是最接近于类的东西了。所以与其说是class,倒不如说是type更加准确。
没有类的js其实就是一群对象在搅。。(哔!)。

要搞清楚js怎么搞对象的,我们需要先理解js两个概念:构造函数与原型。

js构造函数

JavaScript 中的构造函数和其它语言中的构造函数是不同的。 通过 new 关键字方式调用的函数都被认为是构造函数。

也就是说,js 只能通过调用函数是否用了关键字 new,如果你用了,我就把你当做构造函数使用。当然,为了方便区分和其他语言保持一致,原则上构造函数名首字母都应该是大写。

老规矩,还是举个栗子。

function Person(name,age){
    this.name=name;
    this.age=age;
    this.sayName=function(){
        alert(this.name);
    }

}

var p1 =new Person('kan',26);
var P2=new Person('li',27);
p1.sayName();//kan
p2.sayName();//kan

我们通过构造函数创建了两个对象,p1,p2.那么js到底背着我们偷走做了什么?

**1创建一个新的对象
2将构造函数的作用域赋值给这个新的对象(因此这个this就是指代了这个新的对象)
3执行赋值操作
4返回这个新的对象
**

那么如果我们不用new 会怎么样呢?

Person('global',1000);
window.sayName();//global

是的,你没看错,这么调用就是给全部变量增加属性。

但是构造函数虽然好用,还是有问题的:
构造函数的每个方法都要在每个实例上重新构造一遍。

alert(p1.sayName==P2.sayName)//false

而这个函数,我们完全可以是使用的一个,没必要去实现两个。
解决这个问题,我们就需要用到下面我要说的第二个我们需要理解的东西了:原型

js原型

我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象的用途是包含了可以由特定类型的所有实例共享的属性和方法。

用人话来说,这个原型就勉强可以看做模板,是调用这个构造函数时候都一样的东西的公共的东西。用现在流行的话说是大家共享的。

function Person(){

}
Person.prototype.name='kan';
Person.prototype.sayName=function(){
    alert(this.name);
}

var p1 =new Person();
var P2=new Person();
p1.sayName();//kan
alert(p1.sayName==P2.sayName)//true
p1.name=p2.name;//true

我们可以看到,在原型上增加的方法都是共有的,现在p1.sayName==P2.sayName 确实是一样的了,不再是两份了,但是name 本来应该是不同的,现在却变成完全一样的,所以这个也是只是单纯使用原型创建对象的不足,所以我们大多是是构造函数和原型结合来创建对象。属性在构造函数里面,而函数则增加到原型的对象里面。

下面是原型和构造函数的关系、

那么既然已经知道了这个关系,我们是否可以在此基础上想出来js是怎么实现继承的呢?

下面就要将js继承的关键:原型链

原型链是一种机制,指的是JavaScript每个对象包括原型对象都有一个内置的[[proto]]属性指向创建它的函数对象的原型对象,即prototype属性。

我们现在新建一个学生构造函数,来演示一下什么是原型链。

function Student(){
}
Student.prototype=p1;
var s1=new Student();
s1.sayName();//kan

为了方便理解,我们先看下面这张图就明白我们做了什么:

我们用一个实例对象P1做Student构造函数的原型,这样S1和S2也都有了Person原型里面的方法和属性,也就是实现了继承。

这个就是原型链,而js内置的原生类型也是这样实现继承的,当然这里面最上面的跟的原型肯定是Object构造函数的原型。

那么我们把它补全。

理解了上面这张图,基本也就理解了js的对象对象程序设计。

原型链的问题我们已经很清楚了,所以推荐的方式还是和构造函数一起使用组合继承的方式。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值